diff --git a/debian_iso_image.inc b/debian_iso_image.inc index 3c90959a..1a2d104e 100644 --- a/debian_iso_image.inc +++ b/debian_iso_image.inc @@ -1,8 +1,8 @@ # List of packages to be included/installed in ISO # bnxt_en - Broadcom kernel modules -#bnxt-en -#bnxt-en-rt +bnxt-en +bnxt-en-rt #intel-i40e i40e @@ -54,7 +54,7 @@ linux-perf #mlnx-ofa_kernel mlnx-ofed-kernel-modules mlnx-ofed-kernel-modules-rt -#mlnx-ofed-kernel-utils +mlnx-ofed-kernel-utils #qat20 qat2.0.l diff --git a/debian_pkg_dirs b/debian_pkg_dirs index 9607ec84..8298e5bd 100644 --- a/debian_pkg_dirs +++ b/debian_pkg_dirs @@ -1,5 +1,5 @@ kernel-std -#kernel-modules/bnxt_en +kernel-modules/bnxt_en kernel-modules/intel-i40e kernel-modules/intel-iavf kernel-modules/intel-ice diff --git a/debian_pkg_dirs_rt b/debian_pkg_dirs_rt index c8d100f6..42776daf 100644 --- a/debian_pkg_dirs_rt +++ b/debian_pkg_dirs_rt @@ -1,5 +1,5 @@ kernel-rt -#kernel-modules/bnxt_en +kernel-modules/bnxt_en kernel-modules/intel-i40e kernel-modules/intel-iavf kernel-modules/intel-ice diff --git a/kernel-modules/bnxt_en/debian/deb_folder/changelog b/kernel-modules/bnxt_en/debian/deb_folder/changelog index a1770b4c..2c27aa02 100644 --- a/kernel-modules/bnxt_en/debian/deb_folder/changelog +++ b/kernel-modules/bnxt_en/debian/deb_folder/changelog @@ -1,3 +1,11 @@ +bnxt-en (1.10.2.227.0.130.0-1) unstable; urgency=medium + + * Upgrade the release of the out-of-tree bnxt_en driver to 1.10.2-227.0.130.0 + for StarlingX. This driver corresponds to "netxtreme-bnxt_en-1.10.2-227.0.130.0.tar.gz" in + Broadcom's "bcm_227.1.111.0" release. + + -- Jiping Ma Mon, 08 Apr 2024 15:46:23 +0800 + bnxt-en (1.10.2.220.0.13.0-1) unstable; urgency=medium * Initial release of the out-of-tree bnxt_en driver for StarlingX. This diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0001-bnxt_re-Makefile-Adapt-to-mlnx-ofa_kernel-for-Starli.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0001-bnxt_re-Makefile-Adapt-to-mlnx-ofa_kernel-for-Starli.patch index 236cae46..ff45fdd0 100644 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/0001-bnxt_re-Makefile-Adapt-to-mlnx-ofa_kernel-for-Starli.patch +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0001-bnxt_re-Makefile-Adapt-to-mlnx-ofa_kernel-for-Starli.patch @@ -1,7 +1,8 @@ -From 8df4ad6c7e42a1d3e0753716d62efa35b7eb6891 Mon Sep 17 00:00:00 2001 +From 6cb55956bc72f255626510ee30e612b23cbff0ab Mon Sep 17 00:00:00 2001 From: "M. Vefa Bicakci" Date: Fri, 4 Feb 2022 18:27:53 -0500 -Subject: [PATCH] bnxt_re/Makefile: Adapt to mlnx-ofa_kernel for StarlingX +Subject: [PATCH 01/10] bnxt_re/Makefile: Adapt to mlnx-ofa_kernel for + StarlingX This patch adapts the bnxt_re kernel module's Makefile to mlnx-ofa_kernel for Debian-based StarlingX. @@ -42,14 +43,16 @@ Here is a summary of the changes: WARNING: Symbol version dump "/Module.symvers" is missing. Signed-off-by: M. Vefa Bicakci +[jm: Adapted the patch for context change] +Signed-off-by: Jiping Ma --- - bnxt_re-220.0.12.0/Makefile | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) + bnxt_re-227.0.130.0/Makefile | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) -diff --git a/bnxt_re-220.0.12.0/Makefile b/bnxt_re-220.0.12.0/Makefile -index 532fb8025465..702d4a81c6f2 100644 ---- a/bnxt_re-220.0.12.0/Makefile -+++ b/bnxt_re-220.0.12.0/Makefile +diff --git a/bnxt_re-227.0.130.0/Makefile b/bnxt_re-227.0.130.0/Makefile +index a9c6104..600698c 100644 +--- a/bnxt_re-227.0.130.0/Makefile ++++ b/bnxt_re-227.0.130.0/Makefile @@ -59,6 +59,8 @@ endif ifneq ($(KDIR),) LINUX=$(KDIR) @@ -59,12 +62,12 @@ index 532fb8025465..702d4a81c6f2 100644 endif ifeq ($(shell ls $(LINUXSRC)/include/uapi > /dev/null 2>&1 && echo uapi),) -@@ -90,26 +92,32 @@ ifeq ($(OFED_VERSION), ) +@@ -89,24 +91,25 @@ ifeq ($(OFED_VERSION), ) endif #find OFED version and compat-includes -ofed_major=$(filter OFED-3.% OFED-4.%, $(OFED_VERSION)) -+ofed_major=$(filter OFED-3.% OFED-4.% 5.%, $(OFED_VERSION)) ++ofed_major=$(filter OFED-3.% OFED-4.% 5.% 23.%, $(OFED_VERSION)) ifneq ($(ofed_major), ) -exists=$(shell if [ -e /usr/src/compat-rdma$(OFED_VERSION) ];\ +exists=$(shell if [ -e /usr/src/ofa_kernel-$(OFED_VERSION) ];\ @@ -81,7 +84,7 @@ index 532fb8025465..702d4a81c6f2 100644 +OFA_KERNEL_PATH=/usr/src/ofa_kernel/default EXTRA_CFLAGS += -DOFED_3_x -ofed_4_17_x=$(filter OFED-4.17%, $(ofed_major)) -+ofed_4_17_x=$(filter OFED-4.17% 5.%, $(ofed_major)) ++ofed_4_17_x=$(filter OFED-4.17% 5.% 23.%, $(ofed_major)) ifneq ($(ofed_4_17_x), ) EXTRA_CFLAGS += -D__OFED_BUILD__ endif @@ -90,15 +93,8 @@ index 532fb8025465..702d4a81c6f2 100644 AUTOCONF_H = -include $(shell /bin/ls -1 $(LINUX)/include/*/autoconf.h 2> /dev/null | head -1) +AUTOCONF_H += -include $(LINUXSRC)/include/linux/kconfig.h endif #end non 3.x OFED -+ -+ifneq ($(BNXT_PEER_MEM_INC),) - KBUILD_EXTRA_SYMBOLS := $(BNXT_PEER_MEM_INC)/Module.symvers -+else -+KBUILD_EXTRA_SYMBOLS := -+endif ifeq (OFED-NATIVE, $(findstring OFED-NATIVE, $(OFED_VERSION))) - ifeq ($(KERNELRELEASE),) -- -2.25.1 +2.43.0 diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-Rename-page_pool.h-to-page_pool-helpers.h.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-Rename-page_pool.h-to-page_pool-helpers.h.patch new file mode 100644 index 00000000..3a0d2d53 --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-Rename-page_pool.h-to-page_pool-helpers.h.patch @@ -0,0 +1,88 @@ +From b9ce5c292b8cc4da2fa2f4ee7ea0220242447991 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 06:54:11 +0000 +Subject: [PATCH 02/10] bnxt_en: Rename page_pool.h to page_pool/helpers.h + +This patch accommodates commit a9ca9f9ceff3 ("page_pool: split types and +declarations from page_pool.h") merged in the v6.6 development cycle, by +applying a similar change to the out-of-tree bnxt_en driver to resolve +the compilation errors encountered with the v6.6 kernel, which are listed +below. + +References: +* https://git.yoctoproject.org/linux-yocto/commit/?h=a9ca9f9ceff3 + +Resolved compilation errors: + +bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h:2581: error: "page_pool_release_page"\ + redefined [-Werror] + 2581 | #define page_pool_release_page(pp, page) + | +In file included from /<>/bnxt_en-1.10.2-227.0.130.0/bnxt.c:80: +bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h:1893: note: this is the location of\ + the previous definition + 1893 | #define page_pool_release_page(page_pool, page) + | +bnxt_en-1.10.2-227.0.130.0/bnxt.c:102:10: fatal error: net/page_pool.h: No\ + such file or directory + 102 | #include + | ^~~~~~~~~~~~~~~~~ + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/Makefile | 4 ++-- + bnxt_en-1.10.2-227.0.130.0/bnxt.c | 2 +- + bnxt_en-1.10.2-227.0.130.0/bnxt_xdp.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/Makefile b/bnxt_en-1.10.2-227.0.130.0/Makefile +index 6237767..2331171 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/Makefile ++++ b/bnxt_en-1.10.2-227.0.130.0/Makefile +@@ -753,7 +753,7 @@ ifneq ($(shell grep -so "xdp_data_hard_end" $(LINUXSRC)/include/net/xdp.h),) + DISTRO_CFLAG += -DHAVE_XDP_FRAME_SZ + endif + +-ifneq ($(shell grep -so "page_pool_release_page" $(LINUXSRC)/include/net/page_pool.h),) ++ifneq ($(shell grep -so "page_pool_release_page" $(LINUXSRC)/include/net/page_pool/helpers.h),) + DISTRO_CFLAG += -DHAVE_PAGE_POOL_RELEASE_PAGE + endif + +@@ -1224,7 +1224,7 @@ ifneq ($(shell grep -so "hwmon_notify_event" $(LINUXSRC)/include/linux/hwmon.h), + DISTRO_CFLAG += -DHAVE_HWMON_NOTIFY_EVENT + endif + +-ifneq ($(shell grep -so "page_pool_dev_alloc_frag" $(LINUXSRC)/include/net/page_pool.h),) ++ifneq ($(shell grep -so "page_pool_dev_alloc_frag" $(LINUXSRC)/include/net/page_pool/helpers.h),) + DISTRO_CFLAG += -DHAVE_PAGE_POOL_PAGE_FRAG + endif + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt.c b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +index 611dcaa..f464809 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +@@ -99,7 +99,7 @@ + #include "bnxt_debugfs.h" + #include "bnxt_coredump.h" + #ifdef CONFIG_PAGE_POOL +-#include ++#include + #ifdef HAVE_XDP_MULTI_BUFF + #include + #endif +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt_xdp.c b/bnxt_en-1.10.2-227.0.130.0/bnxt_xdp.c +index 4b15c9a..42469c7 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt_xdp.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt_xdp.c +@@ -25,7 +25,7 @@ + #include "bnxt.h" + #include "bnxt_xdp.h" + #ifdef CONFIG_PAGE_POOL +-#include ++#include + #endif + + DEFINE_STATIC_KEY_FALSE(bnxt_xdp_locking_key); +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-bnxt_compat.h-Fix-up-a-build-failure.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-bnxt_compat.h-Fix-up-a-build-failure.patch deleted file mode 100644 index 2dc66170..00000000 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/0002-bnxt_en-bnxt_compat.h-Fix-up-a-build-failure.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 861bb6919cf76ca93c0f41fab8fbd2178aba08c3 Mon Sep 17 00:00:00 2001 -From: "M. Vefa Bicakci" -Date: Fri, 4 Feb 2022 19:44:06 -0500 -Subject: [PATCH] bnxt_en/bnxt_compat.h: Fix up a build failure - -This commit resolves the following build failure: - - In file included from ./include/net/sock.h:59, - from ./include/linux/tcp.h:19, - from ./include/linux/ipv6.h:87, - from ./include/net/dsfield.h:12, - from ./include/net/ip_tunnels.h:13, - from ./include/net/dst_metadata.h:6, - from /builddir/build/BUILD/netxtreme-bnxt_en-1.10.2-219.0.55.0/bnxt_en-1.10.2-219.0.55.0/bnxt.h:30, - from /builddir/build/BUILD/netxtreme-bnxt_en-1.10.2-219.0.55.0/bnxt_en-1.10.2-219.0.55.0/bnxt_hwrm.c:26: - ./include/linux/filter.h:980:1: error: useless type name in empty declaration [-Werror] - void bpf_warn_invalid_xdp_action(u32 act); - ^~~~ - cc1: all warnings being treated as errors - -The problem arises from the fact that the function -bpf_warn_invalid_xdp_action is already defined in the kernel. Having a -placeholder macro definition with the same name causes the compilation -warning (which turns into an error due to -Werror). - -Signed-off-by: M. Vefa Bicakci ---- - bnxt_en-1.10.2-220.0.13.0/bnxt_compat.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/bnxt_en-1.10.2-220.0.13.0/bnxt_compat.h b/bnxt_en-1.10.2-220.0.13.0/bnxt_compat.h -index 63d27f2e8979..aeb15fc9ab2a 100644 ---- a/bnxt_en-1.10.2-220.0.13.0/bnxt_compat.h -+++ b/bnxt_en-1.10.2-220.0.13.0/bnxt_compat.h -@@ -1596,7 +1596,6 @@ enum xdp_action { - - #ifndef HAVE_BPF_TRACE - #define trace_xdp_exception(dev, xdp_prog, act) --#define bpf_warn_invalid_xdp_action(act) - #endif - - #ifdef HAVE_XDP_RXQ_INFO --- -2.25.1 - diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-fix-the-build-errors.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-fix-the-build-errors.patch new file mode 100644 index 00000000..aaa33f6d --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-fix-the-build-errors.patch @@ -0,0 +1,62 @@ +From cbeba2c17eb7bc5a64e90eceae08908e6be16e36 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 07:15:18 +0000 +Subject: [PATCH 03/10] bnxt_en: fix the build errors + +We encounter the following two build errors. + +1. "page_pool_release_page" redefined. +bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h:2581: error: "page_pool_release_page"\ + redefined [-Werror] + 2581 | #define page_pool_release_page(pp, page) + | +In file included from /<>/bnxt_en-1.10.2-227.0.130.0/bnxt.c:80: +bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h:1893: note: this is the location of \ + the previous definition + 1893 | #define page_pool_release_page(page_pool, page) + +2. conversion from enum cfa_tcam_mgr_device_type to enum + cfa_tcam_mgr_tbl_type. +bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c:982:32: error: implicit \ + conversion from enum cfa_tcam_mgr_device_type to enum cfa_tcam_mgr_tbl_type\ + [-Werror=enum-conversion] + 982 | cfa_tcam_mgr_tbl_2_str(type), + | ^~~~ + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h | 4 ---- + bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c | 2 +- + 2 files changed, 1 insertion(+), 5 deletions(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h b/bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h +index 652724f..df93a73 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt_compat.h +@@ -2577,10 +2577,6 @@ struct netlink_ext_ack { + #define skb_mark_for_recycle(skb) skb_mark_for_recycle(skb, page, rxr->page_pool) + #endif + +-#ifdef HAVE_SKB_MARK_RECYCLE +-#define page_pool_release_page(pp, page) +-#endif +- + #ifdef CONFIG_BNXT_HWMON + #include + #ifndef HWMON_CHANNEL_INFO +diff --git a/bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c b/bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c +index 08b90d4..7a0d9fc 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c ++++ b/bnxt_en-1.10.2-227.0.130.0/tf_core/cfa_tcam_mgr.c +@@ -979,7 +979,7 @@ int cfa_tcam_mgr_init(struct tf *tfp, enum cfa_tcam_mgr_device_type type, + netdev_dbg(tfp->bp->dev, + "%s: %s End row is OOR(%d >= %d)\n", + tf_dir_2_str(dir), +- cfa_tcam_mgr_tbl_2_str(type), ++ cfa_tcam_mgr_tbl_2_str((enum cfa_tcam_mgr_tbl_type)type), + table_data->end_row, + table_data->num_rows); + return -EFAULT; +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-skb_frag_fill_page_desc-replace-of-__skb_fra.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-skb_frag_fill_page_desc-replace-of-__skb_fra.patch new file mode 100644 index 00000000..38cb807e --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-skb_frag_fill_page_desc-replace-of-__skb_fra.patch @@ -0,0 +1,60 @@ +From 87beff6c0d67f5ae8f088a49469bf5262d75023b Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 07:30:05 +0000 +Subject: [PATCH 04/10] bnxt_en: skb_frag_fill_page_desc() replace of + __skb_frag_set_page + +This patch accommodates commit 278fda0d52f6 ("net: remove __skb_frag_set_page()") +merged in the v6.5 development cycle, by applying a similar change to the +out-of-tree bnxt_en driver to resolve the compilation errors encountered with +the v6.6 kernel, which are listed below. + +References: +* https://git.yoctoproject.org/linux-yocto/commit/?h=b51f4113ebb0 +* https://git.yoctoproject.org/linux-yocto/commit/?h=278fda0d52f6 + +Resolved compilation errors: + +bnxt_en-1.10.2-227.0.130.0/bnxt.c: In function __bnxt_rx_agg_pages: +bnxt_en-1.10.2-227.0.130.0/bnxt.c:1545:3: error: implicit declaration\ + of function __skb_frag_set_page; did you mean skb_frag_page? \ + [-Werror=implicit-function-declaration] + 1545 | __skb_frag_set_page(frag, cons_rx_buf->page); + | ^~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/bnxt.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt.c b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +index f464809..b763655 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +@@ -1540,9 +1540,8 @@ static u32 __bnxt_rx_agg_pages(struct bnxt *bp, + RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; + + cons_rx_buf = &rxr->rx_agg_ring[cons]; +- skb_frag_off_set(frag, cons_rx_buf->offset); +- skb_frag_size_set(frag, frag_len); +- __skb_frag_set_page(frag, cons_rx_buf->page); ++ skb_frag_fill_page_desc(frag, cons_rx_buf->page, ++ cons_rx_buf->offset, frag_len); + shinfo->nr_frags = i + 1; + __clear_bit(cons, rxr->rx_agg_bmap); + +@@ -1558,10 +1557,7 @@ static u32 __bnxt_rx_agg_pages(struct bnxt *bp, + xdp_buff_set_frag_pfmemalloc(xdp); + + if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_ATOMIC) != 0) { +- unsigned int nr_frags; +- +- nr_frags = --shinfo->nr_frags; +- __skb_frag_set_page(&shinfo->frags[nr_frags], NULL); ++ --shinfo->nr_frags; + cons_rx_buf->page = page; + + /* Update prod since possibly some pages have been +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_en-Drop-redundant-pci_enable_pcie_error_reporti.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_en-Drop-redundant-pci_enable_pcie_error_reporti.patch new file mode 100644 index 00000000..7234b955 --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_en-Drop-redundant-pci_enable_pcie_error_reporti.patch @@ -0,0 +1,58 @@ +From 71d56c87a2fdbcc600e39867d462ea40ca4260ad Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 07:33:11 +0000 +Subject: [PATCH 05/10] bnxt_en: Drop redundant + pci_enable_pcie_error_reporting() + +This commit accommodates commit 7ec4b34be423 ("PCI/AER: Unexport +pci_enable_pcie_error_reporting()") merged in the v6.6 development cycle, +by applying changes similar to the ones found in commit 5f29b73d4eba +("bnxt: Drop redundant pci_enable_pcie_error_reporting() +") to resolve the bnxt_en driver compilation failures encountered with +the v6.6 kernel, which are listed below. + +References: +* https://git.yoctoproject.org/linux-yocto/commit/?h=5f29b73d4eba + +Resolved compilation errors: + +bnxt_en-1.10.2-227.0.130.0/bnxt.c:16658:2: error: implicit declaration\ + of function pci_enable_pcie_error_reporting \ + [-Werror=implicit-function-declaration] +16658 | pci_enable_pcie_error_reporting(pdev); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bnxt_en-1.10.2-227.0.130.0/bnxt.c: In function bnxt_remove_one: +bnxt_en-1.10.2-227.0.130.0/bnxt.c:17632:2: error: implicit declaration\ + of function pci_disable_pcie_error_reporting \ + [-Werror=implicit-function-declaration] +17632 | pci_disable_pcie_error_reporting(pdev); + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/bnxt.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt.c b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +index b763655..1ccdb79 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +@@ -16651,8 +16651,6 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) + goto init_err_release; + } + +- pci_enable_pcie_error_reporting(pdev); +- + INIT_WORK(&bp->sp_task, bnxt_sp_task); + INIT_DELAYED_WORK(&bp->fw_reset_task, bnxt_fw_reset_task); + +@@ -17625,7 +17623,6 @@ static void bnxt_remove_one(struct pci_dev *pdev) + devlink_port_type_clear(&bp->dl_port); + #endif + bnxt_ptp_clear(bp); +- pci_disable_pcie_error_reporting(pdev); + unregister_netdev(dev); + bnxt_dbr_exit(bp); + clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_re-Fix-the-version-compatibility-issue.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_re-Fix-the-version-compatibility-issue.patch deleted file mode 100644 index a7c43b90..00000000 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/0005-bnxt_re-Fix-the-version-compatibility-issue.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 4b2ec2164007df4b380dcf6f27b5110b7f1e3855 Mon Sep 17 00:00:00 2001 -From: Jiping Ma -Date: Mon, 6 Nov 2023 18:02:02 -0800 -Subject: [PATCH] bnxt_re: Fix the version compatibility issue - -We meet the version compatibility issue after upgrading mlnx-ofa_kernel -to 5.9. mlnx-ofa_kernel-5.5 is based on linux kernel 5.13-rc4. -mlnx-ofa_kernel-5.9 is based on linux kernel v6.0-rc5. We adapt bnxt_re -to mlnx-ofa_kernel-5.9 by referring to the following two upstream -commits and the bnxt_re-227.0.130.0 source code. - -The definition of create_qp() was changed with the following commit -https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15-rc6&id=514aee660df493cd673154a6ba6bab745ec47b8c - -IB_DEVICE_LOCAL_DMA_LKEY was removed with the following commit -https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.0.y&id=e945c653c8e972d1b81a88e474d79f801b60213a - -bnxt_re-220.0.12.0/main.c:1340:16: error: initialization of init \ - (*)(struct ib_qp *, struct ib_qp_init_attr *, struct ib_udata *) \ - from incompatible pointer type struct ib_qp * (*)(struct ib_pd *, \ - struct ib_qp_init_attr *, struct ib_udata *) - [-Werror=incompatible-pointer-types] - 1340 | .create_qp = bnxt_re_create_qp, - | ^~~~~~~~~~~~~~~~~ -bnxt_re-220.0.12.0/ib_verbs.c:160:11: error: IB_DEVICE_LOCAL_DMA_LKEY \ - undeclared (first use in this function); did you mean \ - IBK_LOCAL_DMA_LKEY? - 160 | | IB_DEVICE_LOCAL_DMA_LKEY - | ^~~~~~~~~~~~~~~~~~~~~~~~ - -Signed-off-by: Jiping Ma ---- - bnxt_re-220.0.12.0/Makefile | 4 ++++ - bnxt_re-220.0.12.0/ib_verbs.c | 29 ++++++++++++----------------- - bnxt_re-220.0.12.0/ib_verbs.h | 7 +++---- - bnxt_re-220.0.12.0/main.c | 1 + - 4 files changed, 20 insertions(+), 21 deletions(-) - -diff --git a/bnxt_re-220.0.12.0/Makefile b/bnxt_re-220.0.12.0/Makefile -index 702d4a8..e36c307 100644 ---- a/bnxt_re-220.0.12.0/Makefile -+++ b/bnxt_re-220.0.12.0/Makefile -@@ -744,6 +744,10 @@ ifneq ($(shell grep "smac" $(OFA_KERNEL_PATH)/include/rdma/ib_verbs.h),) - DISTRO_CFLAG += -DHAVE_IB_WC_SMAC - endif - -+ifneq ($(shell grep "ib_kernel_cap_flags" $(OFA_KERNEL_PATH)/include/rdma/ib_verbs.h),) -+ DISTRO_CFLAG += -DHAVE_IB_KERNEL_CAP_FLAGS -+endif -+ - EXTRA_CFLAGS += ${DISTRO_CFLAG} -DFPGA -g -DCONFIG_BNXT_SRIOV \ - -DCONFIG_BNXT_DCB -DENABLE_DEBUGFS -DCONFIG_BNXT_RE \ - -DBIND_MW_FENCE_WQE -DPOST_QP1_DUMMY_WQE -diff --git a/bnxt_re-220.0.12.0/ib_verbs.c b/bnxt_re-220.0.12.0/ib_verbs.c -index 7b9e77d..24120c5 100644 ---- a/bnxt_re-220.0.12.0/ib_verbs.c -+++ b/bnxt_re-220.0.12.0/ib_verbs.c -@@ -157,7 +157,9 @@ int bnxt_re_query_device(struct ib_device *ibdev, - | IB_DEVICE_RC_RNR_NAK_GEN - | IB_DEVICE_SHUTDOWN_PORT - | IB_DEVICE_SYS_IMAGE_GUID -+#ifndef HAVE_IB_KERNEL_CAP_FLAGS - | IB_DEVICE_LOCAL_DMA_LKEY -+#endif - | IB_DEVICE_RESIZE_MAX_WR - | IB_DEVICE_PORT_ACTIVE_EVENT - | IB_DEVICE_N_NOTIFY_CQ -@@ -221,6 +223,9 @@ int bnxt_re_query_device(struct ib_device *ibdev, - ib_attr->sig_prot_cap = 0; - ib_attr->sig_guard_cap = 0; - ib_attr->odp_caps.general_caps = 0; -+#endif -+#ifdef HAVE_IB_KERNEL_CAP_FLAGS -+ ib_attr->kernel_cap_flags = IBK_LOCAL_DMA_LKEY; - #endif - return 0; - } -@@ -1832,7 +1837,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp - rdev->gsi_ctx.gsi_sqp) { - rc = bnxt_re_destroy_gsi_sqp(qp); - if (rc) -- goto sh_fail; -+ return rc; - } - bnxt_qplib_free_hdr_buf(&rdev->qplib_res, &qp->qplib_qp); - } -@@ -1841,11 +1846,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp - ib_umem_release(qp->rumem); - if (qp->sumem && !IS_ERR(qp->sumem)) - ib_umem_release(qp->sumem); -- kfree(qp); - - return 0; --sh_fail: -- return rc; - } - - static u8 __from_ib_qp_type(enum ib_qp_type type) -@@ -2605,14 +2607,15 @@ static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev, - return rc; - } - --struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, -+int bnxt_re_create_qp(struct ib_qp *ib_qp, - struct ib_qp_init_attr *qp_init_attr, - struct ib_udata *udata) - { -+ struct ib_pd *ib_pd = ib_qp->pd; - struct bnxt_re_pd *pd = to_bnxt_re(ib_pd, struct bnxt_re_pd, ib_pd); - struct bnxt_qplib_dev_attr *dev_attr; - struct bnxt_re_dev *rdev; -- struct bnxt_re_qp *qp; -+ struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); - int rc; - - rdev = pd->rdev; -@@ -2621,15 +2624,9 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, - rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr); - if (!rc) { - rc = -EINVAL; -- goto exit; -+ goto fail; - } - -- qp = kzalloc(sizeof(*qp), GFP_KERNEL); -- if (!qp) { -- dev_err(rdev_to_dev(rdev), "Allocate QP failed!"); -- rc = -ENOMEM; -- goto exit; -- } - qp->rdev = rdev; - - rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata); -@@ -2677,7 +2674,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, - - bnxt_re_qp_info_add_qpinfo(rdev, qp); - -- return &qp->ib_qp; -+ return 0; - - qp_destroy: - bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); -@@ -2689,9 +2686,7 @@ free_umem: - ib_umem_release(qp->sumem); - } - fail: -- kfree(qp); --exit: -- return ERR_PTR(rc); -+ return rc; - } - - static int bnxt_re_modify_shadow_qp(struct bnxt_re_dev *rdev, -diff --git a/bnxt_re-220.0.12.0/ib_verbs.h b/bnxt_re-220.0.12.0/ib_verbs.h -index 5c5d3b9..257a3cb 100644 ---- a/bnxt_re-220.0.12.0/ib_verbs.h -+++ b/bnxt_re-220.0.12.0/ib_verbs.h -@@ -121,9 +121,9 @@ struct bnxt_re_qp_info_entry { - }; - - struct bnxt_re_qp { -+ struct ib_qp ib_qp; - struct list_head list; - struct bnxt_re_dev *rdev; -- struct ib_qp ib_qp; - spinlock_t sq_lock; - spinlock_t rq_lock; - struct bnxt_qplib_qp qplib_qp; -@@ -333,9 +333,8 @@ DESTROY_SRQ_RET bnxt_re_destroy_srq(struct ib_srq *srq - ); - int bnxt_re_post_srq_recv(struct ib_srq *ib_srq, CONST_STRUCT ib_recv_wr *wr, - CONST_STRUCT ib_recv_wr **bad_wr); --struct ib_qp *bnxt_re_create_qp(struct ib_pd *pd, -- struct ib_qp_init_attr *qp_init_attr, -- struct ib_udata *udata); -+int bnxt_re_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *qp_init_attr, -+ struct ib_udata *udata); - int bnxt_re_modify_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, - int qp_attr_mask, struct ib_udata *udata); - int bnxt_re_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, -diff --git a/bnxt_re-220.0.12.0/main.c b/bnxt_re-220.0.12.0/main.c -index 61010bb..dcd3212 100644 ---- a/bnxt_re-220.0.12.0/main.c -+++ b/bnxt_re-220.0.12.0/main.c -@@ -1416,6 +1416,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = { - #ifdef HAVE_CQ_ALLOC_IN_IB_CORE - INIT_RDMA_OBJ_SIZE(ib_cq, bnxt_re_cq, ib_cq), - #endif -+ INIT_RDMA_OBJ_SIZE(ib_qp, bnxt_re_qp, ib_qp), - #ifdef HAVE_UCONTEXT_ALLOC_IN_IB_CORE - INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx), - #endif --- -2.42.0 - diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0006-bnxt_en-Use-64bits-for-used_keys.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0006-bnxt_en-Use-64bits-for-used_keys.patch new file mode 100644 index 00000000..161a8320 --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0006-bnxt_en-Use-64bits-for-used_keys.patch @@ -0,0 +1,41 @@ +From d7b26be91901d084d78b97583f328efb09b5d637 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 07:55:36 +0000 +Subject: [PATCH 06/10] bnxt_en: Use 64bits for used_keys + +As 32bits of dissector->used_keys are exhausted, +increase the size to 64bits. change 0x%x to 0x%llx to fix the +following build error. + +References: +* https://git.yoctoproject.org/linux-yocto/commit/?h=2b3082c6ef3b + +bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c:679:24: error: format \ + expects argument of type unsigned int, but argument 4 has \ + type long long unsigned int [-Werror=format=] + 679 | netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x\n", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 680 | dissector->used_keys); + | ~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c b/bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c +index 6a1bcac..39879be 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt_tc.c +@@ -676,7 +676,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp, + /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */ + if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 || + (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) { +- netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x\n", ++ netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%llx\n", + dissector->used_keys); + return -EOPNOTSUPP; + } +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0007-bnxt_en-remove-module-from-class_create.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0007-bnxt_en-remove-module-from-class_create.patch new file mode 100644 index 00000000..3b003e4b --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0007-bnxt_en-remove-module-from-class_create.patch @@ -0,0 +1,49 @@ +From a3309f86fe1c3f7829b1f9673e6278f76a6e754c Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 08:05:40 +0000 +Subject: [PATCH 07/10] bnxt_en: remove module * from class_create() + +This commit accommodates commit dcfbb67e48a2 ("driver core: class: +use lock_class_key already present in struct subsys_private"), +which removes the module pointer. This commit was merged in the +v6.4 development cycle and causes compilation failures with the +v6.6 kernel, which are listed below. + +References: +* https://git.yoctoproject.org/linux-yocto/commit/?h=1aaba11da9aa +* https://git.yoctoproject.org/linux-yocto/commit/?h=dcfbb67e48a2 + +Resolved compilation errors: + +/usr/src/linux-headers-6.6.0-1-common/include/linux/export.h:29:22: \ + error: passing argument 1 of class_create from incompatible pointer\ + type [-Werror=incompatible-pointer-types] + 29 | #define THIS_MODULE (&__this_module) + | ~^~~~~~~~~~~~~~~ + | | + | struct module * +bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c:1180:41: note: in expansion of\ + macro THIS_MODULE + 1180 | blfc_global_dev.d_class = class_create(THIS_MODULE, BNXT_LFC_DEV_NAME); + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c b/bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c +index 16fd078..09729ae 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt_lfc.c +@@ -1177,7 +1177,7 @@ int32_t __init bnxt_lfc_init(void) + return rc; + } + +- blfc_global_dev.d_class = class_create(THIS_MODULE, BNXT_LFC_DEV_NAME); ++ blfc_global_dev.d_class = class_create(BNXT_LFC_DEV_NAME); + if (IS_ERR(blfc_global_dev.d_class)) { + BNXT_LFC_ERR(NULL, "Class creation is failed\n"); + unregister_chrdev_region(blfc_global_dev.d_dev, 1); +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0008-bnxt_en-correct-the-path-for-auxiliary_bus.h.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0008-bnxt_en-correct-the-path-for-auxiliary_bus.h.patch new file mode 100644 index 00000000..7c9a691f --- /dev/null +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0008-bnxt_en-correct-the-path-for-auxiliary_bus.h.patch @@ -0,0 +1,101 @@ +From 833b892b0654611bf84d18dcb932535b33d94601 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Tue, 9 Apr 2024 08:43:38 +0000 +Subject: [PATCH 08/10] bnxt_en: correct the path for auxiliary_bus.h + +auxiliary_bus.h is in /usr/src/linux-headers-6.6.0-1-common, so correct +the path for auxiliary_bus.h to fix the build issue. + +bnxt_re-227.0.130.0/main.c:1032:40: error: implicit declaration of\ + function auxiliary_get_drvdata [-Werror=implicit-function-declaration] + 1032 | struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(handle); + | ^~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Jiping Ma +--- + bnxt_en-1.10.2-227.0.130.0/Makefile | 12 +++++++++--- + bnxt_en-1.10.2-227.0.130.0/bnxt_auxbus_compat.h | 4 ---- + bnxt_re-227.0.130.0/Makefile | 11 ++++++++--- + 3 files changed, 17 insertions(+), 10 deletions(-) + +diff --git a/bnxt_en-1.10.2-227.0.130.0/Makefile b/bnxt_en-1.10.2-227.0.130.0/Makefile +index 2331171..e229cc9 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/Makefile ++++ b/bnxt_en-1.10.2-227.0.130.0/Makefile +@@ -1196,7 +1196,13 @@ ifneq ($(shell grep -so "struct netlink_ext_ack" $(LINUXSRC)/include/linux/netli + DISTRO_CFLAG += -DHAVE_NETLINK_EXT_ACK + endif + +-ifneq ($(shell ls $(LINUXSRC)/include/linux/auxiliary_bus.h > /dev/null 2>&1 && echo auxiliary_driver),) ++ifeq (${KSRC_COMMON},) ++KSRC_AUX := ${LINUXSRC} ++else ++KSRC_AUX := ${KSRC_COMMON} ++endif ++ ++ifneq ($(shell ls $(KSRC_AUX)/include/linux/auxiliary_bus.h > /dev/null 2>&1 && echo auxiliary_driver),) + DISTRO_CFLAG += -DHAVE_AUXILIARY_DRIVER + endif + +@@ -1208,11 +1214,11 @@ ifneq ($(shell grep -o "struct auxiliary_device_id" $(LINUXSRC)/include/linux/mo + DISTRO_CFLAG += -DHAVE_AUX_DEVICE_ID + endif + +-ifneq ($(shell grep -so "auxiliary_set_drvdata" $(LINUXSRC)/include/linux/auxiliary_bus.h),) ++ifneq ($(shell grep -so "auxiliary_set_drvdata" $(KSRC_AUX)/include/linux/auxiliary_bus.h),) + DISTRO_CFLAG += -DHAVE_AUX_SET_DRVDATA + endif + +-ifneq ($(shell grep -so "auxiliary_get_drvdata" $(LINUXSRC)/include/linux/auxiliary_bus.h),) ++ifneq ($(shell grep -so "auxiliary_get_drvdata" $(KSRC_AUX)/include/linux/auxiliary_bus.h),) + DISTRO_CFLAG += -DHAVE_AUX_GET_DRVDATA + endif + +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt_auxbus_compat.h b/bnxt_en-1.10.2-227.0.130.0/bnxt_auxbus_compat.h +index 9496e56..d4b2653 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt_auxbus_compat.h ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt_auxbus_compat.h +@@ -10,10 +10,6 @@ + #ifndef _BNXT_AUXILIARY_COMPAT_H_ + #define _BNXT_AUXILIARY_COMPAT_H_ + +-#if !defined(CONFIG_AUXILIARY_BUS) +-#undef HAVE_AUXILIARY_DRIVER +-#endif +- + #ifdef HAVE_AUXILIARY_DRIVER + #include + #endif +diff --git a/bnxt_re-227.0.130.0/Makefile b/bnxt_re-227.0.130.0/Makefile +index 600698c..21048b9 100644 +--- a/bnxt_re-227.0.130.0/Makefile ++++ b/bnxt_re-227.0.130.0/Makefile +@@ -910,17 +910,22 @@ ifneq ($(shell grep -o "struct auxiliary_device_id" $(LINUXSRC)/include/linux/mo + DISTRO_CFLAG += -DHAVE_AUX_DEVICE_ID + endif + +-ifneq ($(shell ls $(LINUXSRC)/include/linux/auxiliary_bus.h > /dev/null 2>&1 && echo auxiliary_driver),) ++ifeq (${KSRC_COMMON},) ++KSRC_AUX := ${LINUXSRC} ++else ++KSRC_AUX := ${KSRC_COMMON} ++endif ++ifneq ($(shell ls $(KSRC_AUX)/include/linux/auxiliary_bus.h > /dev/null 2>&1 && echo auxiliary_driver),) + ifneq ($(CONFIG_AUXILIARY_BUS),) + DISTRO_CFLAG += -DHAVE_AUXILIARY_DRIVER + endif + endif + +-ifneq ($(shell grep -so "auxiliary_set_drvdata" $(LINUXSRC)/include/linux/auxiliary_bus.h),) ++ifneq ($(shell grep -so "auxiliary_set_drvdata" $(KSRC_AUX)/include/linux/auxiliary_bus.h),) + DISTRO_CFLAG += -DHAVE_AUX_SET_DRVDATA + endif + +-ifneq ($(shell grep -so "auxiliary_get_drvdata" $(LINUXSRC)/include/linux/auxiliary_bus.h),) ++ifneq ($(shell grep -so "auxiliary_get_drvdata" $(KSRC_AUX)/include/linux/auxiliary_bus.h),) + DISTRO_CFLAG += -DHAVE_AUX_GET_DRVDATA + endif + +-- +2.43.0 + diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0009-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch similarity index 84% rename from kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch rename to kernel-modules/bnxt_en/debian/deb_folder/patches/0009-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch index 17cb72c9..8a49a899 100644 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/0003-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0009-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch @@ -1,7 +1,7 @@ -From ad51050d13b3cae78140b1acc507d792646f8503 Mon Sep 17 00:00:00 2001 +From 474236904abea6f8ef1ae3d52245b714e5566b59 Mon Sep 17 00:00:00 2001 From: "M. Vefa Bicakci" Date: Wed, 2 Mar 2022 14:14:12 -0500 -Subject: [PATCH] bnxt_en, bnxt_re: Use irq_update_affinity_hint +Subject: [PATCH 09/10] bnxt_en, bnxt_re: Use irq_update_affinity_hint This commit updates the bnxt_en and bnxt_re device drivers to use the irq_update_affinity_hint function instead of the irq_set_affinity_hint @@ -73,15 +73,15 @@ for completeness. Signed-off-by: M. Vefa Bicakci --- - bnxt_en-1.10.2-220.0.13.0/bnxt.c | 6 +++--- - bnxt_re-220.0.12.0/qplib_fp.c | 6 +++--- + bnxt_en-1.10.2-227.0.130.0/bnxt.c | 6 +++--- + bnxt_re-227.0.130.0/qplib_fp.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) -diff --git a/bnxt_en-1.10.2-220.0.13.0/bnxt.c b/bnxt_en-1.10.2-220.0.13.0/bnxt.c -index b0b99338c425..a2f55dfcd0c3 100644 ---- a/bnxt_en-1.10.2-220.0.13.0/bnxt.c -+++ b/bnxt_en-1.10.2-220.0.13.0/bnxt.c -@@ -10716,7 +10716,7 @@ static void bnxt_free_irq(struct bnxt *bp) +diff --git a/bnxt_en-1.10.2-227.0.130.0/bnxt.c b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +index 1ccdb79..3a61281 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/bnxt.c ++++ b/bnxt_en-1.10.2-227.0.130.0/bnxt.c +@@ -12479,7 +12479,7 @@ static void bnxt_free_irq(struct bnxt *bp) (defined(HAVE_CPUMASK_LOCAL_FIRST) || \ defined(HAVE_CPUMASK_LOCAL_SPREAD)) if (irq->have_cpumask) { @@ -90,7 +90,7 @@ index b0b99338c425..a2f55dfcd0c3 100644 free_cpumask_var(irq->cpu_mask); irq->have_cpumask = 0; } -@@ -10787,10 +10787,10 @@ static int bnxt_request_irq(struct bnxt *bp) +@@ -12554,10 +12554,10 @@ static int bnxt_request_irq(struct bnxt *bp) break; } #endif @@ -103,20 +103,20 @@ index b0b99338c425..a2f55dfcd0c3 100644 irq->vector); break; } -diff --git a/bnxt_re-220.0.12.0/qplib_fp.c b/bnxt_re-220.0.12.0/qplib_fp.c -index ef5f279fcb79..60d2eda3727d 100644 ---- a/bnxt_re-220.0.12.0/qplib_fp.c -+++ b/bnxt_re-220.0.12.0/qplib_fp.c -@@ -492,7 +492,7 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) +diff --git a/bnxt_re-227.0.130.0/qplib_fp.c b/bnxt_re-227.0.130.0/qplib_fp.c +index d7c6d80..ae50c0b 100644 +--- a/bnxt_re-227.0.130.0/qplib_fp.c ++++ b/bnxt_re-227.0.130.0/qplib_fp.c +@@ -518,7 +518,7 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, false); /* Sync with last running IRQ handler */ synchronize_irq(nq->msix_vec); - irq_set_affinity_hint(nq->msix_vec, NULL); + irq_update_affinity_hint(nq->msix_vec, NULL); free_irq(nq->msix_vec, nq); - - /* Cleanup Tasklet */ -@@ -546,10 +546,10 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, + kfree(nq->name); + nq->name = NULL; +@@ -577,10 +577,10 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, cpumask_clear(&nq->mask); cpumask_set_cpu(nq_indx, &nq->mask); @@ -130,5 +130,5 @@ index ef5f279fcb79..60d2eda3727d 100644 nq->requested = true; bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, true); -- -2.25.1 +2.43.0 diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-Makefile-Allow-parallelized-build.patch b/kernel-modules/bnxt_en/debian/deb_folder/patches/0010-bnxt_en-Makefile-Allow-parallelized-build.patch similarity index 69% rename from kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-Makefile-Allow-parallelized-build.patch rename to kernel-modules/bnxt_en/debian/deb_folder/patches/0010-bnxt_en-Makefile-Allow-parallelized-build.patch index 5d79d34b..899cf3f6 100644 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/0004-bnxt_en-Makefile-Allow-parallelized-build.patch +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/0010-bnxt_en-Makefile-Allow-parallelized-build.patch @@ -1,7 +1,7 @@ -From c7555e5087afb22752631dd19b357d9e25cd6760 Mon Sep 17 00:00:00 2001 +From ff80107e1cca82430eceb5719bbb186e4d9ac480 Mon Sep 17 00:00:00 2001 From: "M. Vefa Bicakci" Date: Fri, 15 Apr 2022 04:29:31 +0000 -Subject: [PATCH] bnxt_en/Makefile: Allow parallelized build +Subject: [PATCH 10/10] bnxt_en/Makefile: Allow parallelized build This commit allows bnxt_en's build to be parallelized via the use of "$(MAKE)" instead of "make". Without this change, make for bnxt_en @@ -13,14 +13,14 @@ manner: Signed-off-by: M. Vefa Bicakci --- - bnxt_en-1.10.2-220.0.13.0/Makefile | 4 ++-- + bnxt_en-1.10.2-227.0.130.0/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/bnxt_en-1.10.2-220.0.13.0/Makefile b/bnxt_en-1.10.2-220.0.13.0/Makefile -index fe2c229d17b5..52a25eb11277 100644 ---- a/bnxt_en-1.10.2-220.0.13.0/Makefile -+++ b/bnxt_en-1.10.2-220.0.13.0/Makefile -@@ -1083,9 +1083,9 @@ endef +diff --git a/bnxt_en-1.10.2-227.0.130.0/Makefile b/bnxt_en-1.10.2-227.0.130.0/Makefile +index e229cc9..84c16d2 100644 +--- a/bnxt_en-1.10.2-227.0.130.0/Makefile ++++ b/bnxt_en-1.10.2-227.0.130.0/Makefile +@@ -1364,9 +1364,9 @@ endef default: ifeq ($(CROSS_COMPILE),) @@ -33,5 +33,5 @@ index fe2c229d17b5..52a25eb11277 100644 yocto_all: -- -2.25.1 +2.43.0 diff --git a/kernel-modules/bnxt_en/debian/deb_folder/patches/series b/kernel-modules/bnxt_en/debian/deb_folder/patches/series index 70ef95c2..c4f0f18d 100644 --- a/kernel-modules/bnxt_en/debian/deb_folder/patches/series +++ b/kernel-modules/bnxt_en/debian/deb_folder/patches/series @@ -1,5 +1,10 @@ 0001-bnxt_re-Makefile-Adapt-to-mlnx-ofa_kernel-for-Starli.patch -0002-bnxt_en-bnxt_compat.h-Fix-up-a-build-failure.patch -0003-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch -0004-bnxt_en-Makefile-Allow-parallelized-build.patch -0005-bnxt_re-Fix-the-version-compatibility-issue.patch +0002-bnxt_en-Rename-page_pool.h-to-page_pool-helpers.h.patch +0003-bnxt_en-fix-the-build-errors.patch +0004-bnxt_en-skb_frag_fill_page_desc-replace-of-__skb_fra.patch +0005-bnxt_en-Drop-redundant-pci_enable_pcie_error_reporti.patch +0006-bnxt_en-Use-64bits-for-used_keys.patch +0007-bnxt_en-remove-module-from-class_create.patch +0008-bnxt_en-correct-the-path-for-auxiliary_bus.h.patch +0009-bnxt_en-bnxt_re-Use-irq_update_affinity_hint.patch +0010-bnxt_en-Makefile-Allow-parallelized-build.patch diff --git a/kernel-modules/bnxt_en/debian/deb_folder/rules b/kernel-modules/bnxt_en/debian/deb_folder/rules index f9995948..64225f23 100755 --- a/kernel-modules/bnxt_en/debian/deb_folder/rules +++ b/kernel-modules/bnxt_en/debian/deb_folder/rules @@ -30,6 +30,7 @@ kheaders_name=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep commo kbuild_name=$(shell ls /usr/src | grep linux@KERNEL_TYPE@-headers | grep amd64) kversion=$(shell echo $(kbuild_name) | sed 's/linux@KERNEL_TYPE@-headers-//g') pkg_common_name=bnxt-en-common +export KSRC_COMMON=/usr/src/$(kheaders_name) # "dpkg --status mlnx-ofed-kernel-dev" prints a version line # like the following: diff --git a/kernel-modules/bnxt_en/debian/dl_hook b/kernel-modules/bnxt_en/debian/dl_hook index 1b07b815..f1063740 100755 --- a/kernel-modules/bnxt_en/debian/dl_hook +++ b/kernel-modules/bnxt_en/debian/dl_hook @@ -24,8 +24,8 @@ # building. # Tools needed: mkdir, rm, tar -DL_TARBALL=bcm_220.0.83.0.tar.gz -SRC_TARBALL=Linux/Linux_Driver/netxtreme-bnxt_en-1.10.2-220.0.13.0.tar.gz +DL_TARBALL=bcm_227.1.111.0b.tar.gz +SRC_TARBALL=Linux/Linux_Driver/netxtreme-bnxt_en-1.10.2-227.0.130.0.tar.gz TMPDIR="bcm_tmp" DESTDIR="${1}" diff --git a/kernel-modules/bnxt_en/debian/meta_data.yaml b/kernel-modules/bnxt_en/debian/meta_data.yaml index d15c81e0..ae1a194c 100644 --- a/kernel-modules/bnxt_en/debian/meta_data.yaml +++ b/kernel-modules/bnxt_en/debian/meta_data.yaml @@ -1,14 +1,14 @@ --- -debver: 1.10.2.220.0.13.0 +debver: 1.10.2.227.0.130.0 debname: bnxt-en dl_hook: dl_hook dl_files: - bcm_220.0.83.0.tar.gz: + bcm_227.1.111.0b.tar.gz: topdir: null url: "https://docs.broadcom.com/docs-and-downloads/\ - ethernet-network-adapters/NXE/BRCM_220.0.83.0/\ - bcm_220.0.83.0.tar.gz" - sha256sum: 85bdfc30b4bd3e184e3b57a48055c11085e3b97593f7b4a8347fa50a9d571336 + ethernet-network-adapters/NXE/BRCM_227.1.111.0/\ + bcm_227.1.111.0b.tar.gz" + sha256sum: 184977c9043b64358d65c9412063377ed5fc4d9efb225c31ce5e11f1b16b5418 revision: dist: $STX_DIST GITREVCOUNT: diff --git a/kernel-modules/mlnx-ofa_kernel/debian/patches/0002-mlnx-ofa_kernel-fix-bnxt_re-build-error.patch b/kernel-modules/mlnx-ofa_kernel/debian/patches/0002-mlnx-ofa_kernel-fix-bnxt_re-build-error.patch new file mode 100644 index 00000000..5337bc5e --- /dev/null +++ b/kernel-modules/mlnx-ofa_kernel/debian/patches/0002-mlnx-ofa_kernel-fix-bnxt_re-build-error.patch @@ -0,0 +1,47 @@ +From d05ff19ed3f3bb6bc914135531e4bdb6d332adce Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Thu, 11 Apr 2024 02:48:47 +0000 +Subject: [PATCH] mlnx-ofa_kernel: fix bnxt_re build error + +NETDEV_CHANGEINFODATA already exists as enum 25 in kernel header file +netdevice.h, but it is defined 0x0019 here, so that NETDEV_CHANGEINFODATA +and NETDEV_BONDING_INFO is same value that caused the following errors. + +bnxt_re-227.0.130.0/main.c: In function bnxt_re_task: +bnxt_re-227.0.130.0/main.c:5668:2: error: duplicate case value + 5668 | case NETDEV_CHANGEINFODATA: + | ^~~~ +bnxt_re-227.0.130.0/main.c:5642:2: note: previously used here + 5642 | case NETDEV_BONDING_INFO: + | ^~~~ +bnxt_re-227.0.130.0/main.c: In function bnxt_re_netdev_event: +bnxt_re-227.0.130.0/main.c:5908:2: error: duplicate case value + 5908 | case NETDEV_CHANGEINFODATA: + | ^~~~ +bnxt_re-227.0.130.0/main.c:5870:2: note: previously used here + 5870 | case NETDEV_BONDING_INFO: + | ^~~~ + +Signed-off-by: Jiping Ma +--- + include/linux/netdevice.h | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 277e5a0..756809d 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -24,10 +24,6 @@ + ( (netdev)->ethtool_ops = (ops) ) + #endif + +-#ifndef NETDEV_BONDING_INFO +-#define NETDEV_BONDING_INFO 0x0019 +-#endif +- + static inline int netdev_set_master(struct net_device *dev, + struct net_device *master) + { +-- +2.43.0 + diff --git a/kernel-modules/mlnx-ofa_kernel/debian/patches/series b/kernel-modules/mlnx-ofa_kernel/debian/patches/series index 0bc75636..aa840de7 100644 --- a/kernel-modules/mlnx-ofa_kernel/debian/patches/series +++ b/kernel-modules/mlnx-ofa_kernel/debian/patches/series @@ -1 +1,2 @@ 0001-Enable-mlx5-onboard-udev-name.patch +0002-mlnx-ofa_kernel-fix-bnxt_re-build-error.patch diff --git a/userspace/broadcom/libbnxt_re/debian/deb_folder/changelog b/userspace/broadcom/libbnxt_re/debian/deb_folder/changelog index b982746d..2b352139 100644 --- a/userspace/broadcom/libbnxt_re/debian/deb_folder/changelog +++ b/userspace/broadcom/libbnxt_re/debian/deb_folder/changelog @@ -1,3 +1,11 @@ +libbnxt-re (227.0.130.0-1) unstable; urgency=medium + + * Upgrade the release of the libbnxt_re Infiniband verbs library for StarlingX + to 227.0.130.0 from 220.0.5.0. This library corresponds to + "libbnxt_re-227.0.130.0.tar.gz" in Broadcom's "bcm_227.1.111.0b" release. + + -- Jiping Ma Mon, 15 Apr 2024 09:47:34 +0800 + libbnxt-re (220.0.5.0-1) unstable; urgency=medium * Initial release of the libbnxt_re Infiniband verbs library for StarlingX. diff --git a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0001-rc-compat-Add-headers-from-v37.3.patch b/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0001-rc-compat-Add-headers-from-v37.3.patch deleted file mode 100644 index 6222a40a..00000000 --- a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0001-rc-compat-Add-headers-from-v37.3.patch +++ /dev/null @@ -1,8186 +0,0 @@ -From 0ace34eb5bcc23dacc68285cd43b828331b42262 Mon Sep 17 00:00:00 2001 -From: "M. Vefa Bicakci" -Date: Thu, 31 Mar 2022 15:52:34 -0400 -Subject: [PATCH] rc-compat: Add headers from v37.3 - -All of the headers were copied from rdma-core repository tag "v37.3". We -do not copy from the v36.y tag, because Mellanox's OpenFabrics -Enterprise Distribution (OFED) package in use by StarlingX is based on -rdma-core v37, and we do not need headers from v36 as a result. - -This commit is intended to go away when the vendor releases a version of -libbnxt_re with native support for Mellanox OFED's rdma-core v37 -baseline. - -The only change to the headers were as follows: - -- Some of the #include directives in driver.h were modified to align - them to their counterparts in the v35 directory, by replacing - angle-brackets ('<' and '>') with double quotes ('"') so that the - files in the rc-compat/v37 directory would be used. - -- The following line was added to driver.h: - #define IBV_DEVICE_LIBRARY_EXTENSION rdmav34 - -- kernel-abi_ib_user_verbs.h was generated using a script in the - rdma-core repository as follows: - - python3 ../buildlib/make_abi_structs.py \ - ./rdma/ib_user_verbs.h \ - kernel-abi_ib_user_verbs.h - -- config.h was adapted from src/rc-compat/v35/config.h in libbnxt_re's - source code. - -Signed-off-by: M. Vefa Bicakci ---- - src/rc-compat/v37/ccan/array_size.h | 26 + - src/rc-compat/v37/ccan/bitmap.h | 239 ++++ - src/rc-compat/v37/ccan/build_assert.h | 40 + - src/rc-compat/v37/ccan/check_type.h | 64 + - src/rc-compat/v37/ccan/compiler.h | 230 ++++ - src/rc-compat/v37/ccan/container_of.h | 146 ++ - src/rc-compat/v37/ccan/ilog.h | 151 ++ - src/rc-compat/v37/ccan/list.h | 842 ++++++++++++ - src/rc-compat/v37/ccan/minmax.h | 65 + - src/rc-compat/v37/ccan/str.h | 228 +++ - src/rc-compat/v37/ccan/str_debug.h | 30 + - src/rc-compat/v37/cmd_ioctl.h | 412 ++++++ - src/rc-compat/v37/config.h | 56 + - src/rc-compat/v37/driver.h | 755 ++++++++++ - src/rc-compat/v37/ib_user_verbs.h | 1301 ++++++++++++++++++ - src/rc-compat/v37/kern-abi.h | 322 +++++ - src/rc-compat/v37/kernel-abi_ib_user_verbs.h | 1114 +++++++++++++++ - src/rc-compat/v37/rdma_user_ioctl_cmds.h | 87 ++ - src/rc-compat/v37/util/cl_qmap.h | 970 +++++++++++++ - src/rc-compat/v37/util/compiler.h | 54 + - src/rc-compat/v37/util/mmio.h | 267 ++++ - src/rc-compat/v37/util/node_name_map.h | 19 + - src/rc-compat/v37/util/rdma_nl.h | 52 + - src/rc-compat/v37/util/symver.h | 107 ++ - src/rc-compat/v37/util/udma_barrier.h | 267 ++++ - src/rc-compat/v37/util/util.h | 93 ++ - 26 files changed, 7937 insertions(+) - create mode 100644 src/rc-compat/v37/ccan/array_size.h - create mode 100644 src/rc-compat/v37/ccan/bitmap.h - create mode 100644 src/rc-compat/v37/ccan/build_assert.h - create mode 100644 src/rc-compat/v37/ccan/check_type.h - create mode 100644 src/rc-compat/v37/ccan/compiler.h - create mode 100644 src/rc-compat/v37/ccan/container_of.h - create mode 100644 src/rc-compat/v37/ccan/ilog.h - create mode 100644 src/rc-compat/v37/ccan/list.h - create mode 100644 src/rc-compat/v37/ccan/minmax.h - create mode 100644 src/rc-compat/v37/ccan/str.h - create mode 100644 src/rc-compat/v37/ccan/str_debug.h - create mode 100644 src/rc-compat/v37/cmd_ioctl.h - create mode 100644 src/rc-compat/v37/config.h - create mode 100644 src/rc-compat/v37/driver.h - create mode 100644 src/rc-compat/v37/ib_user_verbs.h - create mode 100644 src/rc-compat/v37/kern-abi.h - create mode 100644 src/rc-compat/v37/kernel-abi_ib_user_verbs.h - create mode 100644 src/rc-compat/v37/rdma_user_ioctl_cmds.h - create mode 100644 src/rc-compat/v37/util/cl_qmap.h - create mode 100644 src/rc-compat/v37/util/compiler.h - create mode 100644 src/rc-compat/v37/util/mmio.h - create mode 100644 src/rc-compat/v37/util/node_name_map.h - create mode 100644 src/rc-compat/v37/util/rdma_nl.h - create mode 100644 src/rc-compat/v37/util/symver.h - create mode 100644 src/rc-compat/v37/util/udma_barrier.h - create mode 100644 src/rc-compat/v37/util/util.h - -diff --git a/src/rc-compat/v37/ccan/array_size.h b/src/rc-compat/v37/ccan/array_size.h -new file mode 100644 -index 000000000000..37b200f5e239 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/array_size.h -@@ -0,0 +1,26 @@ -+/* CC0 (Public domain) - see LICENSE file for details */ -+#ifndef CCAN_ARRAY_SIZE_H -+#define CCAN_ARRAY_SIZE_H -+#include "config.h" -+#include -+ -+/** -+ * ARRAY_SIZE - get the number of elements in a visible array -+ * @arr: the array whose size you want. -+ * -+ * This does not work on pointers, or arrays declared as [], or -+ * function parameters. With correct compiler support, such usage -+ * will cause a build error (see build_assert). -+ */ -+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr)) -+ -+#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF -+/* Two gcc extensions. -+ * &a[0] degrades to a pointer: a different type from an array */ -+#define _array_size_chk(arr) \ -+ BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(arr), \ -+ typeof(&(arr)[0]))) -+#else -+#define _array_size_chk(arr) 0 -+#endif -+#endif /* CCAN_ALIGNOF_H */ -diff --git a/src/rc-compat/v37/ccan/bitmap.h b/src/rc-compat/v37/ccan/bitmap.h -new file mode 100644 -index 000000000000..ff0b8c83da46 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/bitmap.h -@@ -0,0 +1,239 @@ -+/* Licensed under LGPLv2+ - see LICENSE file for details */ -+#ifndef CCAN_BITMAP_H_ -+#define CCAN_BITMAP_H_ -+ -+#include -+#include -+#include -+#include -+ -+typedef unsigned long bitmap_word; -+ -+#define BITMAP_WORD_BITS (sizeof(bitmap_word) * CHAR_BIT) -+#define BITMAP_NWORDS(_n) \ -+ (((_n) + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS) -+ -+/* -+ * We wrap each word in a structure for type checking. -+ */ -+typedef struct { -+ bitmap_word w; -+} bitmap; -+ -+#define BITMAP_DECLARE(_name, _nbits) \ -+ bitmap (_name)[BITMAP_NWORDS(_nbits)] -+ -+static inline size_t bitmap_sizeof(unsigned long nbits) -+{ -+ return BITMAP_NWORDS(nbits) * sizeof(bitmap_word); -+} -+ -+static inline bitmap_word bitmap_bswap(bitmap_word w) -+{ -+ /* We do not need to have the bitmap in any specific endianness */ -+ return w; -+} -+ -+#define BITMAP_WORD(_bm, _n) ((_bm)[(_n) / BITMAP_WORD_BITS].w) -+#define BITMAP_WORDBIT(_n) \ -+ (bitmap_bswap(1UL << (BITMAP_WORD_BITS - ((_n) % BITMAP_WORD_BITS) - 1))) -+ -+#define BITMAP_HEADWORDS(_nbits) \ -+ ((_nbits) / BITMAP_WORD_BITS) -+#define BITMAP_HEADBYTES(_nbits) \ -+ (BITMAP_HEADWORDS(_nbits) * sizeof(bitmap_word)) -+ -+#define BITMAP_TAILWORD(_bm, _nbits) \ -+ ((_bm)[BITMAP_HEADWORDS(_nbits)].w) -+#define BITMAP_HASTAIL(_nbits) (((_nbits) % BITMAP_WORD_BITS) != 0) -+#define BITMAP_TAILBITS(_nbits) \ -+ (bitmap_bswap(~(-1UL >> ((_nbits) % BITMAP_WORD_BITS)))) -+#define BITMAP_TAIL(_bm, _nbits) \ -+ (BITMAP_TAILWORD(_bm, _nbits) & BITMAP_TAILBITS(_nbits)) -+ -+static inline void bitmap_set_bit(bitmap *bmap, unsigned long n) -+{ -+ BITMAP_WORD(bmap, n) |= BITMAP_WORDBIT(n); -+} -+ -+static inline void bitmap_clear_bit(bitmap *bmap, unsigned long n) -+{ -+ BITMAP_WORD(bmap, n) &= ~BITMAP_WORDBIT(n); -+} -+ -+static inline void bitmap_change_bit(bitmap *bmap, unsigned long n) -+{ -+ BITMAP_WORD(bmap, n) ^= BITMAP_WORDBIT(n); -+} -+ -+static inline bool bitmap_test_bit(const bitmap *bmap, unsigned long n) -+{ -+ return !!(BITMAP_WORD(bmap, n) & BITMAP_WORDBIT(n)); -+} -+ -+void bitmap_zero_range(bitmap *bmap, unsigned long n, unsigned long m); -+void bitmap_fill_range(bitmap *bmap, unsigned long n, unsigned long m); -+ -+static inline void bitmap_zero(bitmap *bmap, unsigned long nbits) -+{ -+ memset(bmap, 0, bitmap_sizeof(nbits)); -+} -+ -+static inline void bitmap_fill(bitmap *bmap, unsigned long nbits) -+{ -+ memset(bmap, 0xff, bitmap_sizeof(nbits)); -+} -+ -+static inline void bitmap_copy(bitmap *dst, const bitmap *src, -+ unsigned long nbits) -+{ -+ memcpy(dst, src, bitmap_sizeof(nbits)); -+} -+ -+#define BITMAP_DEF_BINOP(_name, _op) \ -+ static inline void bitmap_##_name(bitmap *dst, bitmap *src1, bitmap *src2, \ -+ unsigned long nbits) \ -+ { \ -+ unsigned long i = 0; \ -+ for (i = 0; i < BITMAP_NWORDS(nbits); i++) { \ -+ dst[i].w = src1[i].w _op src2[i].w; \ -+ } \ -+ } -+ -+BITMAP_DEF_BINOP(and, &) -+BITMAP_DEF_BINOP(or, |) -+BITMAP_DEF_BINOP(xor, ^) -+BITMAP_DEF_BINOP(andnot, & ~) -+ -+#undef BITMAP_DEF_BINOP -+ -+static inline void bitmap_complement(bitmap *dst, const bitmap *src, -+ unsigned long nbits) -+{ -+ unsigned long i; -+ -+ for (i = 0; i < BITMAP_NWORDS(nbits); i++) -+ dst[i].w = ~src[i].w; -+} -+ -+static inline bool bitmap_equal(const bitmap *src1, const bitmap *src2, -+ unsigned long nbits) -+{ -+ return (memcmp(src1, src2, BITMAP_HEADBYTES(nbits)) == 0) -+ && (!BITMAP_HASTAIL(nbits) -+ || (BITMAP_TAIL(src1, nbits) == BITMAP_TAIL(src2, nbits))); -+} -+ -+static inline bool bitmap_intersects(const bitmap *src1, const bitmap *src2, -+ unsigned long nbits) -+{ -+ unsigned long i; -+ -+ for (i = 0; i < BITMAP_HEADWORDS(nbits); i++) { -+ if (src1[i].w & src2[i].w) -+ return true; -+ } -+ if (BITMAP_HASTAIL(nbits) && -+ (BITMAP_TAIL(src1, nbits) & BITMAP_TAIL(src2, nbits))) -+ return true; -+ return false; -+} -+ -+static inline bool bitmap_subset(const bitmap *src1, const bitmap *src2, -+ unsigned long nbits) -+{ -+ unsigned long i; -+ -+ for (i = 0; i < BITMAP_HEADWORDS(nbits); i++) { -+ if (src1[i].w & ~src2[i].w) -+ return false; -+ } -+ if (BITMAP_HASTAIL(nbits) && -+ (BITMAP_TAIL(src1, nbits) & ~BITMAP_TAIL(src2, nbits))) -+ return false; -+ return true; -+} -+ -+static inline bool bitmap_full(const bitmap *bmap, unsigned long nbits) -+{ -+ unsigned long i; -+ -+ for (i = 0; i < BITMAP_HEADWORDS(nbits); i++) { -+ if (bmap[i].w != -1UL) -+ return false; -+ } -+ if (BITMAP_HASTAIL(nbits) && -+ (BITMAP_TAIL(bmap, nbits) != BITMAP_TAILBITS(nbits))) -+ return false; -+ -+ return true; -+} -+ -+static inline bool bitmap_empty(const bitmap *bmap, unsigned long nbits) -+{ -+ unsigned long i; -+ -+ for (i = 0; i < BITMAP_HEADWORDS(nbits); i++) { -+ if (bmap[i].w != 0) -+ return false; -+ } -+ if (BITMAP_HASTAIL(nbits) && (BITMAP_TAIL(bmap, nbits) != 0)) -+ return false; -+ -+ return true; -+} -+ -+unsigned long bitmap_ffs(const bitmap *bmap, -+ unsigned long n, unsigned long m); -+ -+/* -+ * Allocation functions -+ */ -+static inline bitmap *bitmap_alloc(unsigned long nbits) -+{ -+ return malloc(bitmap_sizeof(nbits)); -+} -+ -+static inline bitmap *bitmap_alloc0(unsigned long nbits) -+{ -+ bitmap *bmap; -+ -+ bmap = bitmap_alloc(nbits); -+ if (bmap) -+ bitmap_zero(bmap, nbits); -+ return bmap; -+} -+ -+static inline bitmap *bitmap_alloc1(unsigned long nbits) -+{ -+ bitmap *bmap; -+ -+ bmap = bitmap_alloc(nbits); -+ if (bmap) -+ bitmap_fill(bmap, nbits); -+ return bmap; -+} -+ -+static inline bitmap *bitmap_realloc0(bitmap *bmap, unsigned long obits, -+ unsigned long nbits) -+{ -+ bmap = realloc(bmap, bitmap_sizeof(nbits)); -+ -+ if ((nbits > obits) && bmap) -+ bitmap_zero_range(bmap, obits, nbits); -+ -+ return bmap; -+} -+ -+static inline bitmap *bitmap_realloc1(bitmap *bmap, unsigned long obits, -+ unsigned long nbits) -+{ -+ bmap = realloc(bmap, bitmap_sizeof(nbits)); -+ -+ if ((nbits > obits) && bmap) -+ bitmap_fill_range(bmap, obits, nbits); -+ -+ return bmap; -+} -+ -+#endif /* CCAN_BITMAP_H_ */ -diff --git a/src/rc-compat/v37/ccan/build_assert.h b/src/rc-compat/v37/ccan/build_assert.h -new file mode 100644 -index 000000000000..0ecd7ff36633 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/build_assert.h -@@ -0,0 +1,40 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_BUILD_ASSERT_H -+#define CCAN_BUILD_ASSERT_H -+ -+/** -+ * BUILD_ASSERT - assert a build-time dependency. -+ * @cond: the compile-time condition which must be true. -+ * -+ * Your compile will fail if the condition isn't true, or can't be evaluated -+ * by the compiler. This can only be used within a function. -+ * -+ * Example: -+ * #include -+ * ... -+ * static char *foo_to_char(struct foo *foo) -+ * { -+ * // This code needs string to be at start of foo. -+ * BUILD_ASSERT(offsetof(struct foo, string) == 0); -+ * return (char *)foo; -+ * } -+ */ -+#define BUILD_ASSERT(cond) \ -+ do { (void) sizeof(char [1 - 2*!(cond)]); } while(0) -+ -+/** -+ * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression. -+ * @cond: the compile-time condition which must be true. -+ * -+ * Your compile will fail if the condition isn't true, or can't be evaluated -+ * by the compiler. This can be used in an expression: its value is "0". -+ * -+ * Example: -+ * #define foo_to_char(foo) \ -+ * ((char *)(foo) \ -+ * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0)) -+ */ -+#define BUILD_ASSERT_OR_ZERO(cond) \ -+ (sizeof(char [1 - 2*!(cond)]) - 1) -+ -+#endif /* CCAN_BUILD_ASSERT_H */ -diff --git a/src/rc-compat/v37/ccan/check_type.h b/src/rc-compat/v37/ccan/check_type.h -new file mode 100644 -index 000000000000..a576a5018e01 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/check_type.h -@@ -0,0 +1,64 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_CHECK_TYPE_H -+#define CCAN_CHECK_TYPE_H -+#include "config.h" -+ -+/** -+ * check_type - issue a warning or build failure if type is not correct. -+ * @expr: the expression whose type we should check (not evaluated). -+ * @type: the exact type we expect the expression to be. -+ * -+ * This macro is usually used within other macros to try to ensure that a macro -+ * argument is of the expected type. No type promotion of the expression is -+ * done: an unsigned int is not the same as an int! -+ * -+ * check_type() always evaluates to 0. -+ * -+ * If your compiler does not support typeof, then the best we can do is fail -+ * to compile if the sizes of the types are unequal (a less complete check). -+ * -+ * Example: -+ * // They should always pass a 64-bit value to _set_some_value! -+ * #define set_some_value(expr) \ -+ * _set_some_value((check_type((expr), uint64_t), (expr))) -+ */ -+ -+/** -+ * check_types_match - issue a warning or build failure if types are not same. -+ * @expr1: the first expression (not evaluated). -+ * @expr2: the second expression (not evaluated). -+ * -+ * This macro is usually used within other macros to try to ensure that -+ * arguments are of identical types. No type promotion of the expressions is -+ * done: an unsigned int is not the same as an int! -+ * -+ * check_types_match() always evaluates to 0. -+ * -+ * If your compiler does not support typeof, then the best we can do is fail -+ * to compile if the sizes of the types are unequal (a less complete check). -+ * -+ * Example: -+ * // Do subtraction to get to enclosing type, but make sure that -+ * // pointer is of correct type for that member. -+ * #define container_of(mbr_ptr, encl_type, mbr) \ -+ * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \ -+ * ((encl_type *) \ -+ * ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr)))) -+ */ -+#if HAVE_TYPEOF -+#define check_type(expr, type) \ -+ ((typeof(expr) *)0 != (type *)0) -+ -+#define check_types_match(expr1, expr2) \ -+ ((typeof(expr1) *)0 != (typeof(expr2) *)0) -+#else -+#include -+/* Without typeof, we can only test the sizes. */ -+#define check_type(expr, type) \ -+ BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type)) -+ -+#define check_types_match(expr1, expr2) \ -+ BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2)) -+#endif /* HAVE_TYPEOF */ -+ -+#endif /* CCAN_CHECK_TYPE_H */ -diff --git a/src/rc-compat/v37/ccan/compiler.h b/src/rc-compat/v37/ccan/compiler.h -new file mode 100644 -index 000000000000..cc0d4d1af2ca ---- /dev/null -+++ b/src/rc-compat/v37/ccan/compiler.h -@@ -0,0 +1,230 @@ -+/* CC0 (Public domain) - see LICENSE file for details */ -+#ifndef CCAN_COMPILER_H -+#define CCAN_COMPILER_H -+#include "config.h" -+ -+#ifndef COLD -+/** -+ * COLD - a function is unlikely to be called. -+ * -+ * Used to mark an unlikely code path and optimize appropriately. -+ * It is usually used on logging or error routines. -+ * -+ * Example: -+ * static void COLD moan(const char *reason) -+ * { -+ * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); -+ * } -+ */ -+#define COLD __attribute__((__cold__)) -+#endif -+ -+#ifndef NORETURN -+/** -+ * NORETURN - a function does not return -+ * -+ * Used to mark a function which exits; useful for suppressing warnings. -+ * -+ * Example: -+ * static void NORETURN fail(const char *reason) -+ * { -+ * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); -+ * exit(1); -+ * } -+ */ -+#define NORETURN __attribute__((__noreturn__)) -+#endif -+ -+#ifndef PRINTF_FMT -+/** -+ * PRINTF_FMT - a function takes printf-style arguments -+ * @nfmt: the 1-based number of the function's format argument. -+ * @narg: the 1-based number of the function's first variable argument. -+ * -+ * This allows the compiler to check your parameters as it does for printf(). -+ * -+ * Example: -+ * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...); -+ */ -+#define PRINTF_FMT(nfmt, narg) \ -+ __attribute__((format(__printf__, nfmt, narg))) -+#endif -+ -+#ifndef CONST_FUNCTION -+/** -+ * CONST_FUNCTION - a function's return depends only on its argument -+ * -+ * This allows the compiler to assume that the function will return the exact -+ * same value for the exact same arguments. This implies that the function -+ * must not use global variables, or dereference pointer arguments. -+ */ -+#define CONST_FUNCTION __attribute__((__const__)) -+ -+#ifndef PURE_FUNCTION -+/** -+ * PURE_FUNCTION - a function is pure -+ * -+ * A pure function is one that has no side effects other than it's return value -+ * and uses no inputs other than it's arguments and global variables. -+ */ -+#define PURE_FUNCTION __attribute__((__pure__)) -+#endif -+#endif -+ -+#ifndef UNNEEDED -+/** -+ * UNNEEDED - a variable/function may not be needed -+ * -+ * This suppresses warnings about unused variables or functions, but tells -+ * the compiler that if it is unused it need not emit it into the source code. -+ * -+ * Example: -+ * // With some preprocessor options, this is unnecessary. -+ * static UNNEEDED int counter; -+ * -+ * // With some preprocessor options, this is unnecessary. -+ * static UNNEEDED void add_to_counter(int add) -+ * { -+ * counter += add; -+ * } -+ */ -+#define UNNEEDED __attribute__((__unused__)) -+#endif -+ -+#ifndef NEEDED -+/** -+ * NEEDED - a variable/function is needed -+ * -+ * This suppresses warnings about unused variables or functions, but tells -+ * the compiler that it must exist even if it (seems) unused. -+ * -+ * Example: -+ * // Even if this is unused, these are vital for debugging. -+ * static NEEDED int counter; -+ * static NEEDED void dump_counter(void) -+ * { -+ * printf("Counter is %i\n", counter); -+ * } -+ */ -+#define NEEDED __attribute__((__used__)) -+#endif -+ -+#ifndef UNUSED -+/** -+ * UNUSED - a parameter is unused -+ * -+ * Some compilers (eg. gcc with -W or -Wunused) warn about unused -+ * function parameters. This suppresses such warnings and indicates -+ * to the reader that it's deliberate. -+ * -+ * Example: -+ * // This is used as a callback, so needs to have this prototype. -+ * static int some_callback(void *unused UNUSED) -+ * { -+ * return 0; -+ * } -+ */ -+#define UNUSED __attribute__((__unused__)) -+#endif -+ -+#ifndef IS_COMPILE_CONSTANT -+/** -+ * IS_COMPILE_CONSTANT - does the compiler know the value of this expression? -+ * @expr: the expression to evaluate -+ * -+ * When an expression manipulation is complicated, it is usually better to -+ * implement it in a function. However, if the expression being manipulated is -+ * known at compile time, it is better to have the compiler see the entire -+ * expression so it can simply substitute the result. -+ * -+ * This can be done using the IS_COMPILE_CONSTANT() macro. -+ * -+ * Example: -+ * enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON }; -+ * -+ * // Out-of-line version. -+ * const char *greek_name(enum greek greek); -+ * -+ * // Inline version. -+ * static inline const char *_greek_name(enum greek greek) -+ * { -+ * switch (greek) { -+ * case ALPHA: return "alpha"; -+ * case BETA: return "beta"; -+ * case GAMMA: return "gamma"; -+ * case DELTA: return "delta"; -+ * case EPSILON: return "epsilon"; -+ * default: return "**INVALID**"; -+ * } -+ * } -+ * -+ * // Use inline if compiler knows answer. Otherwise call function -+ * // to avoid copies of the same code everywhere. -+ * #define greek_name(g) \ -+ * (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g)) -+ */ -+#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr) -+#endif -+ -+#ifndef WARN_UNUSED_RESULT -+/** -+ * WARN_UNUSED_RESULT - warn if a function return value is unused. -+ * -+ * Used to mark a function where it is extremely unlikely that the caller -+ * can ignore the result, eg realloc(). -+ * -+ * Example: -+ * // buf param may be freed by this; need return value! -+ * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size) -+ * { -+ * return realloc(buf, (*size) *= 2); -+ * } -+ */ -+#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -+#endif -+ -+ -+/** -+ * WARN_DEPRECATED - warn that a function/type/variable is deprecated when used. -+ * -+ * Used to mark a function, type or variable should not be used. -+ * -+ * Example: -+ * WARN_DEPRECATED char *oldfunc(char *buf); -+ */ -+#define WARN_DEPRECATED __attribute__((__deprecated__)) -+ -+ -+/** -+ * NO_NULL_ARGS - specify that no arguments to this function can be NULL. -+ * -+ * The compiler will warn if any pointer args are NULL. -+ * -+ * Example: -+ * NO_NULL_ARGS char *my_copy(char *buf); -+ */ -+#define NO_NULL_ARGS __attribute__((__nonnull__)) -+ -+/** -+ * NON_NULL_ARGS - specify that some arguments to this function can't be NULL. -+ * @...: 1-based argument numbers for which args can't be NULL. -+ * -+ * The compiler will warn if any of the specified pointer args are NULL. -+ * -+ * Example: -+ * char *my_copy2(char *buf, char *maybenull) NON_NULL_ARGS(1); -+ */ -+#define NON_NULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__))) -+ -+ -+/** -+ * LAST_ARG_NULL - specify the last argument of a variadic function must be NULL. -+ * -+ * The compiler will warn if the last argument isn't NULL. -+ * -+ * Example: -+ * char *join_string(char *buf, ...) LAST_ARG_NULL; -+ */ -+#define LAST_ARG_NULL __attribute__((__sentinel__)) -+ -+#endif /* CCAN_COMPILER_H */ -diff --git a/src/rc-compat/v37/ccan/container_of.h b/src/rc-compat/v37/ccan/container_of.h -new file mode 100644 -index 000000000000..9180f37f0d15 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/container_of.h -@@ -0,0 +1,146 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_CONTAINER_OF_H -+#define CCAN_CONTAINER_OF_H -+#include -+ -+#include "config.h" -+#include -+ -+/** -+ * container_of - get pointer to enclosing structure -+ * @member_ptr: pointer to the structure member -+ * @containing_type: the type this member is within -+ * @member: the name of this member within the structure. -+ * -+ * Given a pointer to a member of a structure, this macro does pointer -+ * subtraction to return the pointer to the enclosing type. -+ * -+ * Example: -+ * struct foo { -+ * int fielda, fieldb; -+ * // ... -+ * }; -+ * struct info { -+ * int some_other_field; -+ * struct foo my_foo; -+ * }; -+ * -+ * static struct info *foo_to_info(struct foo *foo) -+ * { -+ * return container_of(foo, struct info, my_foo); -+ * } -+ */ -+#ifndef container_of -+#define container_of(member_ptr, containing_type, member) \ -+ ((containing_type *) \ -+ ((char *)(member_ptr) \ -+ - container_off(containing_type, member)) \ -+ + check_types_match(*(member_ptr), ((containing_type *)0)->member)) -+#endif -+ -+/** -+ * container_of_or_null - get pointer to enclosing structure, or NULL -+ * @member_ptr: pointer to the structure member -+ * @containing_type: the type this member is within -+ * @member: the name of this member within the structure. -+ * -+ * Given a pointer to a member of a structure, this macro does pointer -+ * subtraction to return the pointer to the enclosing type, unless it -+ * is given NULL, in which case it also returns NULL. -+ * -+ * Example: -+ * struct foo { -+ * int fielda, fieldb; -+ * // ... -+ * }; -+ * struct info { -+ * int some_other_field; -+ * struct foo my_foo; -+ * }; -+ * -+ * static struct info *foo_to_info_allowing_null(struct foo *foo) -+ * { -+ * return container_of_or_null(foo, struct info, my_foo); -+ * } -+ */ -+static inline char *container_of_or_null_(void *member_ptr, size_t offset) -+{ -+ return member_ptr ? (char *)member_ptr - offset : NULL; -+} -+#define container_of_or_null(member_ptr, containing_type, member) \ -+ ((containing_type *) \ -+ container_of_or_null_(member_ptr, \ -+ container_off(containing_type, member)) \ -+ + check_types_match(*(member_ptr), ((containing_type *)0)->member)) -+ -+/** -+ * container_off - get offset to enclosing structure -+ * @containing_type: the type this member is within -+ * @member: the name of this member within the structure. -+ * -+ * Given a pointer to a member of a structure, this macro does -+ * typechecking and figures out the offset to the enclosing type. -+ * -+ * Example: -+ * struct foo { -+ * int fielda, fieldb; -+ * // ... -+ * }; -+ * struct info { -+ * int some_other_field; -+ * struct foo my_foo; -+ * }; -+ * -+ * static struct info *foo_to_info(struct foo *foo) -+ * { -+ * size_t off = container_off(struct info, my_foo); -+ * return (void *)((char *)foo - off); -+ * } -+ */ -+#define container_off(containing_type, member) \ -+ offsetof(containing_type, member) -+ -+/** -+ * container_of_var - get pointer to enclosing structure using a variable -+ * @member_ptr: pointer to the structure member -+ * @container_var: a pointer of same type as this member's container -+ * @member: the name of this member within the structure. -+ * -+ * Given a pointer to a member of a structure, this macro does pointer -+ * subtraction to return the pointer to the enclosing type. -+ * -+ * Example: -+ * static struct info *foo_to_i(struct foo *foo) -+ * { -+ * struct info *i = container_of_var(foo, i, my_foo); -+ * return i; -+ * } -+ */ -+#if HAVE_TYPEOF -+#define container_of_var(member_ptr, container_var, member) \ -+ container_of(member_ptr, typeof(*container_var), member) -+#else -+#define container_of_var(member_ptr, container_var, member) \ -+ ((void *)((char *)(member_ptr) - \ -+ container_off_var(container_var, member))) -+#endif -+ -+/** -+ * container_off_var - get offset of a field in enclosing structure -+ * @container_var: a pointer to a container structure -+ * @member: the name of a member within the structure. -+ * -+ * Given (any) pointer to a structure and a its member name, this -+ * macro does pointer subtraction to return offset of member in a -+ * structure memory layout. -+ * -+ */ -+#if HAVE_TYPEOF -+#define container_off_var(var, member) \ -+ container_off(typeof(*var), member) -+#else -+#define container_off_var(var, member) \ -+ ((const char *)&(var)->member - (const char *)(var)) -+#endif -+ -+#endif /* CCAN_CONTAINER_OF_H */ -diff --git a/src/rc-compat/v37/ccan/ilog.h b/src/rc-compat/v37/ccan/ilog.h -new file mode 100644 -index 000000000000..2793a7056afe ---- /dev/null -+++ b/src/rc-compat/v37/ccan/ilog.h -@@ -0,0 +1,151 @@ -+/* CC0 (Public domain) - see LICENSE file for details */ -+#if !defined(_ilog_H) -+# define _ilog_H (1) -+# include "config.h" -+# include -+# include -+# include -+ -+/** -+ * ilog32 - Integer binary logarithm of a 32-bit value. -+ * @_v: A 32-bit value. -+ * Returns floor(log2(_v))+1, or 0 if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * Note that many uses will resolve to the fast macro version instead. -+ * -+ * See Also: -+ * ilog32_nz(), ilog64() -+ * -+ * Example: -+ * // Rounds up to next power of 2 (if not a power of 2). -+ * static uint32_t round_up32(uint32_t i) -+ * { -+ * assert(i != 0); -+ * return 1U << ilog32(i-1); -+ * } -+ */ -+int ilog32(uint32_t _v); -+ -+/** -+ * ilog32_nz - Integer binary logarithm of a non-zero 32-bit value. -+ * @_v: A 32-bit value. -+ * Returns floor(log2(_v))+1, or undefined if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * Note that many uses will resolve to the fast macro version instead. -+ * See Also: -+ * ilog32(), ilog64_nz() -+ * Example: -+ * // Find Last Set (ie. highest bit set, 0 to 31). -+ * static uint32_t fls32(uint32_t i) -+ * { -+ * assert(i != 0); -+ * return ilog32_nz(i) - 1; -+ * } -+ */ -+int ilog32_nz(uint32_t _v); -+ -+/** -+ * ilog64 - Integer binary logarithm of a 64-bit value. -+ * @_v: A 64-bit value. -+ * Returns floor(log2(_v))+1, or 0 if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * Note that many uses will resolve to the fast macro version instead. -+ * See Also: -+ * ilog64_nz(), ilog32() -+ */ -+int ilog64(uint64_t _v); -+ -+/** -+ * ilog64_nz - Integer binary logarithm of a non-zero 64-bit value. -+ * @_v: A 64-bit value. -+ * Returns floor(log2(_v))+1, or undefined if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * Note that many uses will resolve to the fast macro version instead. -+ * See Also: -+ * ilog64(), ilog32_nz() -+ */ -+int ilog64_nz(uint64_t _v); -+ -+/** -+ * STATIC_ILOG_32 - The integer logarithm of an (unsigned, 32-bit) constant. -+ * @_v: A non-negative 32-bit constant. -+ * Returns floor(log2(_v))+1, or 0 if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * This macro should only be used when you need a compile-time constant, -+ * otherwise ilog32 or ilog32_nz are just as fast and more flexible. -+ * -+ * Example: -+ * #define MY_PAGE_SIZE 4096 -+ * #define MY_PAGE_BITS (STATIC_ILOG_32(PAGE_SIZE) - 1) -+ */ -+#define STATIC_ILOG_32(_v) (STATIC_ILOG5((uint32_t)(_v))) -+ -+/** -+ * STATIC_ILOG_64 - The integer logarithm of an (unsigned, 64-bit) constant. -+ * @_v: A non-negative 64-bit constant. -+ * Returns floor(log2(_v))+1, or 0 if _v==0. -+ * This is the number of bits that would be required to represent _v in two's -+ * complement notation with all of the leading zeros stripped. -+ * This macro should only be used when you need a compile-time constant, -+ * otherwise ilog64 or ilog64_nz are just as fast and more flexible. -+ */ -+#define STATIC_ILOG_64(_v) (STATIC_ILOG6((uint64_t)(_v))) -+ -+/* Private implementation details */ -+ -+/*Note the casts to (int) below: this prevents "upgrading" -+ the type of an entire expression to an (unsigned) size_t.*/ -+#if INT_MAX>=2147483647 && HAVE_BUILTIN_CLZ -+#define builtin_ilog32_nz(v) \ -+ (((int)sizeof(unsigned)*CHAR_BIT) - __builtin_clz(v)) -+#elif LONG_MAX>=2147483647L && HAVE_BUILTIN_CLZL -+#define builtin_ilog32_nz(v) \ -+ (((int)sizeof(unsigned)*CHAR_BIT) - __builtin_clzl(v)) -+#endif -+ -+#if INT_MAX>=9223372036854775807LL && HAVE_BUILTIN_CLZ -+#define builtin_ilog64_nz(v) \ -+ (((int)sizeof(unsigned)*CHAR_BIT) - __builtin_clz(v)) -+#elif LONG_MAX>=9223372036854775807LL && HAVE_BUILTIN_CLZL -+#define builtin_ilog64_nz(v) \ -+ (((int)sizeof(unsigned long)*CHAR_BIT) - __builtin_clzl(v)) -+#elif HAVE_BUILTIN_CLZLL -+#define builtin_ilog64_nz(v) \ -+ (((int)sizeof(unsigned long long)*CHAR_BIT) - __builtin_clzll(v)) -+#endif -+ -+#ifdef builtin_ilog32_nz -+#define ilog32(_v) (builtin_ilog32_nz(_v)&-!!(_v)) -+#define ilog32_nz(_v) builtin_ilog32_nz(_v) -+#else -+#define ilog32_nz(_v) ilog32(_v) -+#define ilog32(_v) (IS_COMPILE_CONSTANT(_v) ? STATIC_ILOG_32(_v) : ilog32(_v)) -+#endif /* builtin_ilog32_nz */ -+ -+#ifdef builtin_ilog64_nz -+#define ilog64(_v) (builtin_ilog64_nz(_v)&-!!(_v)) -+#define ilog64_nz(_v) builtin_ilog64_nz(_v) -+#else -+#define ilog64_nz(_v) ilog64(_v) -+#define ilog64(_v) (IS_COMPILE_CONSTANT(_v) ? STATIC_ILOG_64(_v) : ilog64(_v)) -+#endif /* builtin_ilog64_nz */ -+ -+/* Macros for evaluating compile-time constant ilog. */ -+# define STATIC_ILOG0(_v) (!!(_v)) -+# define STATIC_ILOG1(_v) (((_v)&0x2)?2:STATIC_ILOG0(_v)) -+# define STATIC_ILOG2(_v) (((_v)&0xC)?2+STATIC_ILOG1((_v)>>2):STATIC_ILOG1(_v)) -+# define STATIC_ILOG3(_v) \ -+ (((_v)&0xF0)?4+STATIC_ILOG2((_v)>>4):STATIC_ILOG2(_v)) -+# define STATIC_ILOG4(_v) \ -+ (((_v)&0xFF00)?8+STATIC_ILOG3((_v)>>8):STATIC_ILOG3(_v)) -+# define STATIC_ILOG5(_v) \ -+ (((_v)&0xFFFF0000)?16+STATIC_ILOG4((_v)>>16):STATIC_ILOG4(_v)) -+# define STATIC_ILOG6(_v) \ -+ (((_v)&0xFFFFFFFF00000000ULL)?32+STATIC_ILOG5((_v)>>32):STATIC_ILOG5(_v)) -+ -+#endif /* _ilog_H */ -diff --git a/src/rc-compat/v37/ccan/list.h b/src/rc-compat/v37/ccan/list.h -new file mode 100644 -index 000000000000..f4006660f7ef ---- /dev/null -+++ b/src/rc-compat/v37/ccan/list.h -@@ -0,0 +1,842 @@ -+/* Licensed under MIT - see LICENSE.MIT file for details */ -+#ifndef CCAN_LIST_H -+#define CCAN_LIST_H -+//#define CCAN_LIST_DEBUG 1 -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * struct list_node - an entry in a doubly-linked list -+ * @next: next entry (self if empty) -+ * @prev: previous entry (self if empty) -+ * -+ * This is used as an entry in a linked list. -+ * Example: -+ * struct child { -+ * const char *name; -+ * // Linked list of all us children. -+ * struct list_node list; -+ * }; -+ */ -+struct list_node -+{ -+ struct list_node *next, *prev; -+}; -+ -+/** -+ * struct list_head - the head of a doubly-linked list -+ * @h: the list_head (containing next and prev pointers) -+ * -+ * This is used as the head of a linked list. -+ * Example: -+ * struct parent { -+ * const char *name; -+ * struct list_head children; -+ * unsigned int num_children; -+ * }; -+ */ -+struct list_head -+{ -+ struct list_node n; -+}; -+ -+/** -+ * list_check - check head of a list for consistency -+ * @h: the list_head -+ * @abortstr: the location to print on aborting, or NULL. -+ * -+ * Because list_nodes have redundant information, consistency checking between -+ * the back and forward links can be done. This is useful as a debugging check. -+ * If @abortstr is non-NULL, that will be printed in a diagnostic if the list -+ * is inconsistent, and the function will abort. -+ * -+ * Returns the list head if the list is consistent, NULL if not (it -+ * can never return NULL if @abortstr is set). -+ * -+ * See also: list_check_node() -+ * -+ * Example: -+ * static void dump_parent(struct parent *p) -+ * { -+ * struct child *c; -+ * -+ * printf("%s (%u children):\n", p->name, p->num_children); -+ * list_check(&p->children, "bad child list"); -+ * list_for_each(&p->children, c, list) -+ * printf(" -> %s\n", c->name); -+ * } -+ */ -+struct list_head *list_check(const struct list_head *h, const char *abortstr); -+ -+/** -+ * list_check_node - check node of a list for consistency -+ * @n: the list_node -+ * @abortstr: the location to print on aborting, or NULL. -+ * -+ * Check consistency of the list node is in (it must be in one). -+ * -+ * See also: list_check() -+ * -+ * Example: -+ * static void dump_child(const struct child *c) -+ * { -+ * list_check_node(&c->list, "bad child list"); -+ * printf("%s\n", c->name); -+ * } -+ */ -+struct list_node *list_check_node(const struct list_node *n, -+ const char *abortstr); -+ -+#define LIST_LOC __FILE__ ":" stringify(__LINE__) -+#ifdef CCAN_LIST_DEBUG -+#define list_debug(h, loc) list_check((h), loc) -+#define list_debug_node(n, loc) list_check_node((n), loc) -+#else -+#define list_debug(h, loc) ((void)loc, h) -+#define list_debug_node(n, loc) ((void)loc, n) -+#endif -+ -+/** -+ * LIST_HEAD_INIT - initializer for an empty list_head -+ * @name: the name of the list. -+ * -+ * Explicit initializer for an empty list. -+ * -+ * See also: -+ * LIST_HEAD, list_head_init() -+ * -+ * Example: -+ * static struct list_head my_list = LIST_HEAD_INIT(my_list); -+ */ -+#define LIST_HEAD_INIT(name) { { &(name).n, &(name).n } } -+ -+/** -+ * LIST_HEAD - define and initialize an empty list_head -+ * @name: the name of the list. -+ * -+ * The LIST_HEAD macro defines a list_head and initializes it to an empty -+ * list. It can be prepended by "static" to define a static list_head. -+ * -+ * See also: -+ * LIST_HEAD_INIT, list_head_init() -+ * -+ * Example: -+ * static LIST_HEAD(my_global_list); -+ */ -+#define LIST_HEAD(name) \ -+ struct list_head name = LIST_HEAD_INIT(name) -+ -+/** -+ * list_head_init - initialize a list_head -+ * @h: the list_head to set to the empty list -+ * -+ * Example: -+ * ... -+ * struct parent *parent = malloc(sizeof(*parent)); -+ * -+ * list_head_init(&parent->children); -+ * parent->num_children = 0; -+ */ -+static inline void list_head_init(struct list_head *h) -+{ -+ h->n.next = h->n.prev = &h->n; -+} -+ -+/** -+ * list_node_init - initialize a list_node -+ * @n: the list_node to link to itself. -+ * -+ * You don't need to use this normally! But it lets you list_del(@n) -+ * safely. -+ */ -+static inline void list_node_init(struct list_node *n) -+{ -+ n->next = n->prev = n; -+} -+ -+/** -+ * list_add_after - add an entry after an existing node in a linked list -+ * @h: the list_head to add the node to (for debugging) -+ * @p: the existing list_node to add the node after -+ * @n: the new list_node to add to the list. -+ * -+ * The existing list_node must already be a member of the list. -+ * The new list_node does not need to be initialized; it will be overwritten. -+ * -+ * Example: -+ * struct child c1, c2, c3; -+ * LIST_HEAD(h); -+ * -+ * list_add_tail(&h, &c1.list); -+ * list_add_tail(&h, &c3.list); -+ * list_add_after(&h, &c1.list, &c2.list); -+ */ -+#define list_add_after(h, p, n) list_add_after_(h, p, n, LIST_LOC) -+static inline void list_add_after_(struct list_head *h, -+ struct list_node *p, -+ struct list_node *n, -+ const char *abortstr) -+{ -+ n->next = p->next; -+ n->prev = p; -+ p->next->prev = n; -+ p->next = n; -+ (void)list_debug(h, abortstr); -+} -+ -+/** -+ * list_add - add an entry at the start of a linked list. -+ * @h: the list_head to add the node to -+ * @n: the list_node to add to the list. -+ * -+ * The list_node does not need to be initialized; it will be overwritten. -+ * Example: -+ * struct child *child = malloc(sizeof(*child)); -+ * -+ * child->name = "marvin"; -+ * list_add(&parent->children, &child->list); -+ * parent->num_children++; -+ */ -+#define list_add(h, n) list_add_(h, n, LIST_LOC) -+static inline void list_add_(struct list_head *h, -+ struct list_node *n, -+ const char *abortstr) -+{ -+ list_add_after_(h, &h->n, n, abortstr); -+} -+ -+/** -+ * list_add_before - add an entry before an existing node in a linked list -+ * @h: the list_head to add the node to (for debugging) -+ * @p: the existing list_node to add the node before -+ * @n: the new list_node to add to the list. -+ * -+ * The existing list_node must already be a member of the list. -+ * The new list_node does not need to be initialized; it will be overwritten. -+ * -+ * Example: -+ * list_head_init(&h); -+ * list_add_tail(&h, &c1.list); -+ * list_add_tail(&h, &c3.list); -+ * list_add_before(&h, &c3.list, &c2.list); -+ */ -+#define list_add_before(h, p, n) list_add_before_(h, p, n, LIST_LOC) -+static inline void list_add_before_(struct list_head *h, -+ struct list_node *p, -+ struct list_node *n, -+ const char *abortstr) -+{ -+ n->next = p; -+ n->prev = p->prev; -+ p->prev->next = n; -+ p->prev = n; -+ (void)list_debug(h, abortstr); -+} -+ -+/** -+ * list_add_tail - add an entry at the end of a linked list. -+ * @h: the list_head to add the node to -+ * @n: the list_node to add to the list. -+ * -+ * The list_node does not need to be initialized; it will be overwritten. -+ * Example: -+ * list_add_tail(&parent->children, &child->list); -+ * parent->num_children++; -+ */ -+#define list_add_tail(h, n) list_add_tail_(h, n, LIST_LOC) -+static inline void list_add_tail_(struct list_head *h, -+ struct list_node *n, -+ const char *abortstr) -+{ -+ list_add_before_(h, &h->n, n, abortstr); -+} -+ -+/** -+ * list_empty - is a list empty? -+ * @h: the list_head -+ * -+ * If the list is empty, returns true. -+ * -+ * Example: -+ * assert(list_empty(&parent->children) == (parent->num_children == 0)); -+ */ -+#define list_empty(h) list_empty_(h, LIST_LOC) -+static inline bool list_empty_(const struct list_head *h, const char* abortstr) -+{ -+ (void)list_debug(h, abortstr); -+ return h->n.next == &h->n; -+} -+ -+/** -+ * list_empty_nodebug - is a list empty (and don't perform debug checks)? -+ * @h: the list_head -+ * -+ * If the list is empty, returns true. -+ * This differs from list_empty() in that if CCAN_LIST_DEBUG is set it -+ * will NOT perform debug checks. Only use this function if you REALLY -+ * know what you're doing. -+ * -+ * Example: -+ * assert(list_empty_nodebug(&parent->children) == (parent->num_children == 0)); -+ */ -+#ifndef CCAN_LIST_DEBUG -+#define list_empty_nodebug(h) list_empty(h) -+#else -+static inline bool list_empty_nodebug(const struct list_head *h) -+{ -+ return h->n.next == &h->n; -+} -+#endif -+ -+/** -+ * list_empty_nocheck - is a list empty? -+ * @h: the list_head -+ * -+ * If the list is empty, returns true. This doesn't perform any -+ * debug check for list consistency, so it can be called without -+ * locks, racing with the list being modified. This is ok for -+ * checks where an incorrect result is not an issue (optimized -+ * bail out path for example). -+ */ -+static inline bool list_empty_nocheck(const struct list_head *h) -+{ -+ return h->n.next == &h->n; -+} -+ -+/** -+ * list_del - delete an entry from an (unknown) linked list. -+ * @n: the list_node to delete from the list. -+ * -+ * Note that this leaves @n in an undefined state; it can be added to -+ * another list, but not deleted again. -+ * -+ * See also: -+ * list_del_from(), list_del_init() -+ * -+ * Example: -+ * list_del(&child->list); -+ * parent->num_children--; -+ */ -+#define list_del(n) list_del_(n, LIST_LOC) -+static inline void list_del_(struct list_node *n, const char* abortstr) -+{ -+ (void)list_debug_node(n, abortstr); -+ n->next->prev = n->prev; -+ n->prev->next = n->next; -+#ifdef CCAN_LIST_DEBUG -+ /* Catch use-after-del. */ -+ n->next = n->prev = NULL; -+#endif -+} -+ -+/** -+ * list_del_init - delete a node, and reset it so it can be deleted again. -+ * @n: the list_node to be deleted. -+ * -+ * list_del(@n) or list_del_init() again after this will be safe, -+ * which can be useful in some cases. -+ * -+ * See also: -+ * list_del_from(), list_del() -+ * -+ * Example: -+ * list_del_init(&child->list); -+ * parent->num_children--; -+ */ -+#define list_del_init(n) list_del_init_(n, LIST_LOC) -+static inline void list_del_init_(struct list_node *n, const char *abortstr) -+{ -+ list_del_(n, abortstr); -+ list_node_init(n); -+} -+ -+/** -+ * list_del_from - delete an entry from a known linked list. -+ * @h: the list_head the node is in. -+ * @n: the list_node to delete from the list. -+ * -+ * This explicitly indicates which list a node is expected to be in, -+ * which is better documentation and can catch more bugs. -+ * -+ * See also: list_del() -+ * -+ * Example: -+ * list_del_from(&parent->children, &child->list); -+ * parent->num_children--; -+ */ -+static inline void list_del_from(struct list_head *h, struct list_node *n) -+{ -+#ifdef CCAN_LIST_DEBUG -+ { -+ /* Thorough check: make sure it was in list! */ -+ struct list_node *i; -+ for (i = h->n.next; i != n; i = i->next) -+ assert(i != &h->n); -+ } -+#endif /* CCAN_LIST_DEBUG */ -+ -+ /* Quick test that catches a surprising number of bugs. */ -+ assert(!list_empty(h)); -+ list_del(n); -+} -+ -+/** -+ * list_swap - swap out an entry from an (unknown) linked list for a new one. -+ * @o: the list_node to replace from the list. -+ * @n: the list_node to insert in place of the old one. -+ * -+ * Note that this leaves @o in an undefined state; it can be added to -+ * another list, but not deleted/swapped again. -+ * -+ * See also: -+ * list_del() -+ * -+ * Example: -+ * struct child x1, x2; -+ * LIST_HEAD(xh); -+ * -+ * list_add(&xh, &x1.list); -+ * list_swap(&x1.list, &x2.list); -+ */ -+#define list_swap(o, n) list_swap_(o, n, LIST_LOC) -+static inline void list_swap_(struct list_node *o, -+ struct list_node *n, -+ const char* abortstr) -+{ -+ (void)list_debug_node(o, abortstr); -+ *n = *o; -+ n->next->prev = n; -+ n->prev->next = n; -+#ifdef CCAN_LIST_DEBUG -+ /* Catch use-after-del. */ -+ o->next = o->prev = NULL; -+#endif -+} -+ -+/** -+ * list_entry - convert a list_node back into the structure containing it. -+ * @n: the list_node -+ * @type: the type of the entry -+ * @member: the list_node member of the type -+ * -+ * Example: -+ * // First list entry is children.next; convert back to child. -+ * child = list_entry(parent->children.n.next, struct child, list); -+ * -+ * See Also: -+ * list_top(), list_for_each() -+ */ -+#define list_entry(n, type, member) container_of(n, type, member) -+ -+/** -+ * list_top - get the first entry in a list -+ * @h: the list_head -+ * @type: the type of the entry -+ * @member: the list_node member of the type -+ * -+ * If the list is empty, returns NULL. -+ * -+ * Example: -+ * struct child *first; -+ * first = list_top(&parent->children, struct child, list); -+ * if (!first) -+ * printf("Empty list!\n"); -+ */ -+#define list_top(h, type, member) \ -+ ((type *)list_top_((h), list_off_(type, member))) -+ -+static inline const void *list_top_(const struct list_head *h, size_t off) -+{ -+ if (list_empty(h)) -+ return NULL; -+ return (const char *)h->n.next - off; -+} -+ -+/** -+ * list_pop - remove the first entry in a list -+ * @h: the list_head -+ * @type: the type of the entry -+ * @member: the list_node member of the type -+ * -+ * If the list is empty, returns NULL. -+ * -+ * Example: -+ * struct child *one; -+ * one = list_pop(&parent->children, struct child, list); -+ * if (!one) -+ * printf("Empty list!\n"); -+ */ -+#define list_pop(h, type, member) \ -+ ((type *)list_pop_((h), list_off_(type, member))) -+ -+static inline const void *list_pop_(const struct list_head *h, size_t off) -+{ -+ struct list_node *n; -+ -+ if (list_empty(h)) -+ return NULL; -+ n = h->n.next; -+ list_del(n); -+ return (const char *)n - off; -+} -+ -+/** -+ * list_tail - get the last entry in a list -+ * @h: the list_head -+ * @type: the type of the entry -+ * @member: the list_node member of the type -+ * -+ * If the list is empty, returns NULL. -+ * -+ * Example: -+ * struct child *last; -+ * last = list_tail(&parent->children, struct child, list); -+ * if (!last) -+ * printf("Empty list!\n"); -+ */ -+#define list_tail(h, type, member) \ -+ ((type *)list_tail_((h), list_off_(type, member))) -+ -+static inline const void *list_tail_(const struct list_head *h, size_t off) -+{ -+ if (list_empty(h)) -+ return NULL; -+ return (const char *)h->n.prev - off; -+} -+ -+/** -+ * list_for_each - iterate through a list. -+ * @h: the list_head (warning: evaluated multiple times!) -+ * @i: the structure containing the list_node -+ * @member: the list_node member of the structure -+ * -+ * This is a convenient wrapper to iterate @i over the entire list. It's -+ * a for loop, so you can break and continue as normal. -+ * -+ * Example: -+ * list_for_each(&parent->children, child, list) -+ * printf("Name: %s\n", child->name); -+ */ -+#define list_for_each(h, i, member) \ -+ list_for_each_off(h, i, list_off_var_(i, member)) -+ -+/** -+ * list_for_each_rev - iterate through a list backwards. -+ * @h: the list_head -+ * @i: the structure containing the list_node -+ * @member: the list_node member of the structure -+ * -+ * This is a convenient wrapper to iterate @i over the entire list. It's -+ * a for loop, so you can break and continue as normal. -+ * -+ * Example: -+ * list_for_each_rev(&parent->children, child, list) -+ * printf("Name: %s\n", child->name); -+ */ -+#define list_for_each_rev(h, i, member) \ -+ list_for_each_rev_off(h, i, list_off_var_(i, member)) -+ -+/** -+ * list_for_each_rev_safe - iterate through a list backwards, -+ * maybe during deletion -+ * @h: the list_head -+ * @i: the structure containing the list_node -+ * @nxt: the structure containing the list_node -+ * @member: the list_node member of the structure -+ * -+ * This is a convenient wrapper to iterate @i over the entire list backwards. -+ * It's a for loop, so you can break and continue as normal. The extra -+ * variable * @nxt is used to hold the next element, so you can delete @i -+ * from the list. -+ * -+ * Example: -+ * struct child *next; -+ * list_for_each_rev_safe(&parent->children, child, next, list) { -+ * printf("Name: %s\n", child->name); -+ * } -+ */ -+#define list_for_each_rev_safe(h, i, nxt, member) \ -+ list_for_each_rev_safe_off(h, i, nxt, list_off_var_(i, member)) -+ -+/** -+ * list_for_each_safe - iterate through a list, maybe during deletion -+ * @h: the list_head -+ * @i: the structure containing the list_node -+ * @nxt: the structure containing the list_node -+ * @member: the list_node member of the structure -+ * -+ * This is a convenient wrapper to iterate @i over the entire list. It's -+ * a for loop, so you can break and continue as normal. The extra variable -+ * @nxt is used to hold the next element, so you can delete @i from the list. -+ * -+ * Example: -+ * list_for_each_safe(&parent->children, child, next, list) { -+ * list_del(&child->list); -+ * parent->num_children--; -+ * } -+ */ -+#define list_for_each_safe(h, i, nxt, member) \ -+ list_for_each_safe_off(h, i, nxt, list_off_var_(i, member)) -+ -+/** -+ * list_next - get the next entry in a list -+ * @h: the list_head -+ * @i: a pointer to an entry in the list. -+ * @member: the list_node member of the structure -+ * -+ * If @i was the last entry in the list, returns NULL. -+ * -+ * Example: -+ * struct child *second; -+ * second = list_next(&parent->children, first, list); -+ * if (!second) -+ * printf("No second child!\n"); -+ */ -+#define list_next(h, i, member) \ -+ ((list_typeof(i))list_entry_or_null(list_debug(h, \ -+ __FILE__ ":" stringify(__LINE__)), \ -+ (i)->member.next, \ -+ list_off_var_((i), member))) -+ -+/** -+ * list_prev - get the previous entry in a list -+ * @h: the list_head -+ * @i: a pointer to an entry in the list. -+ * @member: the list_node member of the structure -+ * -+ * If @i was the first entry in the list, returns NULL. -+ * -+ * Example: -+ * first = list_prev(&parent->children, second, list); -+ * if (!first) -+ * printf("Can't go back to first child?!\n"); -+ */ -+#define list_prev(h, i, member) \ -+ ((list_typeof(i))list_entry_or_null(list_debug(h, \ -+ __FILE__ ":" stringify(__LINE__)), \ -+ (i)->member.prev, \ -+ list_off_var_((i), member))) -+ -+/** -+ * list_append_list - empty one list onto the end of another. -+ * @to: the list to append into -+ * @from: the list to empty. -+ * -+ * This takes the entire contents of @from and moves it to the end of -+ * @to. After this @from will be empty. -+ * -+ * Example: -+ * struct list_head adopter; -+ * -+ * list_append_list(&adopter, &parent->children); -+ * assert(list_empty(&parent->children)); -+ * parent->num_children = 0; -+ */ -+#define list_append_list(t, f) list_append_list_(t, f, \ -+ __FILE__ ":" stringify(__LINE__)) -+static inline void list_append_list_(struct list_head *to, -+ struct list_head *from, -+ const char *abortstr) -+{ -+ struct list_node *from_tail = list_debug(from, abortstr)->n.prev; -+ struct list_node *to_tail = list_debug(to, abortstr)->n.prev; -+ -+ /* Sew in head and entire list. */ -+ to->n.prev = from_tail; -+ from_tail->next = &to->n; -+ to_tail->next = &from->n; -+ from->n.prev = to_tail; -+ -+ /* Now remove head. */ -+ list_del(&from->n); -+ list_head_init(from); -+} -+ -+/** -+ * list_prepend_list - empty one list into the start of another. -+ * @to: the list to prepend into -+ * @from: the list to empty. -+ * -+ * This takes the entire contents of @from and moves it to the start -+ * of @to. After this @from will be empty. -+ * -+ * Example: -+ * list_prepend_list(&adopter, &parent->children); -+ * assert(list_empty(&parent->children)); -+ * parent->num_children = 0; -+ */ -+#define list_prepend_list(t, f) list_prepend_list_(t, f, LIST_LOC) -+static inline void list_prepend_list_(struct list_head *to, -+ struct list_head *from, -+ const char *abortstr) -+{ -+ struct list_node *from_tail = list_debug(from, abortstr)->n.prev; -+ struct list_node *to_head = list_debug(to, abortstr)->n.next; -+ -+ /* Sew in head and entire list. */ -+ to->n.next = &from->n; -+ from->n.prev = &to->n; -+ to_head->prev = from_tail; -+ from_tail->next = to_head; -+ -+ /* Now remove head. */ -+ list_del(&from->n); -+ list_head_init(from); -+} -+ -+/* internal macros, do not use directly */ -+#define list_for_each_off_dir_(h, i, off, dir) \ -+ for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ -+ (off)); \ -+ list_node_from_off_((void *)i, (off)) != &(h)->n; \ -+ i = list_node_to_off_(list_node_from_off_((void *)i, (off))->dir, \ -+ (off))) -+ -+#define list_for_each_safe_off_dir_(h, i, nxt, off, dir) \ -+ for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ -+ (off)), \ -+ nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ -+ (off)); \ -+ list_node_from_off_(i, (off)) != &(h)->n; \ -+ i = nxt, \ -+ nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ -+ (off))) -+ -+/** -+ * list_for_each_off - iterate through a list of memory regions. -+ * @h: the list_head -+ * @i: the pointer to a memory region wich contains list node data. -+ * @off: offset(relative to @i) at which list node data resides. -+ * -+ * This is a low-level wrapper to iterate @i over the entire list, used to -+ * implement all oher, more high-level, for-each constructs. It's a for loop, -+ * so you can break and continue as normal. -+ * -+ * WARNING! Being the low-level macro that it is, this wrapper doesn't know -+ * nor care about the type of @i. The only assumtion made is that @i points -+ * to a chunk of memory that at some @offset, relative to @i, contains a -+ * properly filled `struct node_list' which in turn contains pointers to -+ * memory chunks and it's turtles all the way down. Whith all that in mind -+ * remember that given the wrong pointer/offset couple this macro will -+ * happilly churn all you memory untill SEGFAULT stops it, in other words -+ * caveat emptor. -+ * -+ * It is worth mentioning that one of legitimate use-cases for that wrapper -+ * is operation on opaque types with known offset for `struct list_node' -+ * member(preferably 0), because it allows you not to disclose the type of -+ * @i. -+ * -+ * Example: -+ * list_for_each_off(&parent->children, child, -+ * offsetof(struct child, list)) -+ * printf("Name: %s\n", child->name); -+ */ -+#define list_for_each_off(h, i, off) \ -+ list_for_each_off_dir_((h),(i),(off),next) -+ -+/** -+ * list_for_each_rev_off - iterate through a list of memory regions backwards -+ * @h: the list_head -+ * @i: the pointer to a memory region wich contains list node data. -+ * @off: offset(relative to @i) at which list node data resides. -+ * -+ * See list_for_each_off for details -+ */ -+#define list_for_each_rev_off(h, i, off) \ -+ list_for_each_off_dir_((h),(i),(off),prev) -+ -+/** -+ * list_for_each_safe_off - iterate through a list of memory regions, maybe -+ * during deletion -+ * @h: the list_head -+ * @i: the pointer to a memory region wich contains list node data. -+ * @nxt: the structure containing the list_node -+ * @off: offset(relative to @i) at which list node data resides. -+ * -+ * For details see `list_for_each_off' and `list_for_each_safe' -+ * descriptions. -+ * -+ * Example: -+ * list_for_each_safe_off(&parent->children, child, -+ * next, offsetof(struct child, list)) -+ * printf("Name: %s\n", child->name); -+ */ -+#define list_for_each_safe_off(h, i, nxt, off) \ -+ list_for_each_safe_off_dir_((h),(i),(nxt),(off),next) -+ -+/** -+ * list_for_each_rev_safe_off - iterate backwards through a list of -+ * memory regions, maybe during deletion -+ * @h: the list_head -+ * @i: the pointer to a memory region wich contains list node data. -+ * @nxt: the structure containing the list_node -+ * @off: offset(relative to @i) at which list node data resides. -+ * -+ * For details see `list_for_each_rev_off' and `list_for_each_rev_safe' -+ * descriptions. -+ * -+ * Example: -+ * list_for_each_rev_safe_off(&parent->children, child, -+ * next, offsetof(struct child, list)) -+ * printf("Name: %s\n", child->name); -+ */ -+#define list_for_each_rev_safe_off(h, i, nxt, off) \ -+ list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev) -+ -+/* Other -off variants. */ -+#define list_entry_off(n, type, off) \ -+ ((type *)list_node_from_off_((n), (off))) -+ -+#define list_head_off(h, type, off) \ -+ ((type *)list_head_off((h), (off))) -+ -+#define list_tail_off(h, type, off) \ -+ ((type *)list_tail_((h), (off))) -+ -+#define list_add_off(h, n, off) \ -+ list_add((h), list_node_from_off_((n), (off))) -+ -+#define list_del_off(n, off) \ -+ list_del(list_node_from_off_((n), (off))) -+ -+#define list_del_from_off(h, n, off) \ -+ list_del_from(h, list_node_from_off_((n), (off))) -+ -+/* Offset helper functions so we only single-evaluate. */ -+static inline void *list_node_to_off_(struct list_node *node, size_t off) -+{ -+ return (void *)((char *)node - off); -+} -+static inline struct list_node *list_node_from_off_(void *ptr, size_t off) -+{ -+ return (struct list_node *)((char *)ptr + off); -+} -+ -+/* Get the offset of the member, but make sure it's a list_node. */ -+#define list_off_(type, member) \ -+ (container_off(type, member) + \ -+ check_type(((type *)0)->member, struct list_node)) -+ -+#define list_off_var_(var, member) \ -+ (container_off_var(var, member) + \ -+ check_type(var->member, struct list_node)) -+ -+#if HAVE_TYPEOF -+#define list_typeof(var) typeof(var) -+#else -+#define list_typeof(var) void * -+#endif -+ -+/* Returns member, or NULL if at end of list. */ -+static inline void *list_entry_or_null(const struct list_head *h, -+ const struct list_node *n, -+ size_t off) -+{ -+ if (n == &h->n) -+ return NULL; -+ return (char *)n - off; -+} -+#endif /* CCAN_LIST_H */ -diff --git a/src/rc-compat/v37/ccan/minmax.h b/src/rc-compat/v37/ccan/minmax.h -new file mode 100644 -index 000000000000..ab6c55472b9a ---- /dev/null -+++ b/src/rc-compat/v37/ccan/minmax.h -@@ -0,0 +1,65 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_MINMAX_H -+#define CCAN_MINMAX_H -+ -+#include "config.h" -+ -+#include -+ -+#if !HAVE_STATEMENT_EXPR || !HAVE_TYPEOF -+/* -+ * Without these, there's no way to avoid unsafe double evaluation of -+ * the arguments -+ */ -+#error Sorry, minmax module requires statement expressions and typeof -+#endif -+ -+#if HAVE_BUILTIN_TYPES_COMPATIBLE_P -+#define MINMAX_ASSERT_COMPATIBLE(a, b) \ -+ BUILD_ASSERT(__builtin_types_compatible_p(a, b)) -+#else -+#define MINMAX_ASSERT_COMPATIBLE(a, b) \ -+ do { } while (0) -+#endif -+ -+#define min(a, b) \ -+ ({ \ -+ typeof(a) _a = (a); \ -+ typeof(b) _b = (b); \ -+ MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ -+ _a < _b ? _a : _b; \ -+ }) -+ -+#define max(a, b) \ -+ ({ \ -+ typeof(a) _a = (a); \ -+ typeof(b) _b = (b); \ -+ MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ -+ _a > _b ? _a : _b; \ -+ }) -+ -+#define clamp(v, f, c) (max(min((v), (c)), (f))) -+ -+ -+#define min_t(t, a, b) \ -+ ({ \ -+ t _ta = (a); \ -+ t _tb = (b); \ -+ min(_ta, _tb); \ -+ }) -+#define max_t(t, a, b) \ -+ ({ \ -+ t _ta = (a); \ -+ t _tb = (b); \ -+ max(_ta, _tb); \ -+ }) -+ -+#define clamp_t(t, v, f, c) \ -+ ({ \ -+ t _tv = (v); \ -+ t _tf = (f); \ -+ t _tc = (c); \ -+ clamp(_tv, _tf, _tc); \ -+ }) -+ -+#endif /* CCAN_MINMAX_H */ -diff --git a/src/rc-compat/v37/ccan/str.h b/src/rc-compat/v37/ccan/str.h -new file mode 100644 -index 000000000000..68c8a518b700 ---- /dev/null -+++ b/src/rc-compat/v37/ccan/str.h -@@ -0,0 +1,228 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_STR_H -+#define CCAN_STR_H -+#include "config.h" -+#include -+#include -+#include -+#include -+ -+/** -+ * streq - Are two strings equal? -+ * @a: first string -+ * @b: first string -+ * -+ * This macro is arguably more readable than "!strcmp(a, b)". -+ * -+ * Example: -+ * if (streq(somestring, "")) -+ * printf("String is empty!\n"); -+ */ -+#define streq(a,b) (strcmp((a),(b)) == 0) -+ -+/** -+ * strstarts - Does this string start with this prefix? -+ * @str: string to test -+ * @prefix: prefix to look for at start of str -+ * -+ * Example: -+ * if (strstarts(somestring, "foo")) -+ * printf("String %s begins with 'foo'!\n", somestring); -+ */ -+#define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0) -+ -+/** -+ * strends - Does this string end with this postfix? -+ * @str: string to test -+ * @postfix: postfix to look for at end of str -+ * -+ * Example: -+ * if (strends(somestring, "foo")) -+ * printf("String %s end with 'foo'!\n", somestring); -+ */ -+static inline bool strends(const char *str, const char *postfix) -+{ -+ if (strlen(str) < strlen(postfix)) -+ return false; -+ -+ return streq(str + strlen(str) - strlen(postfix), postfix); -+} -+ -+/** -+ * stringify - Turn expression into a string literal -+ * @expr: any C expression -+ * -+ * Example: -+ * #define PRINT_COND_IF_FALSE(cond) \ -+ * ((cond) || printf("%s is false!", stringify(cond))) -+ */ -+#define stringify(expr) stringify_1(expr) -+/* Double-indirection required to stringify expansions */ -+#define stringify_1(expr) #expr -+ -+/** -+ * strcount - Count number of (non-overlapping) occurrences of a substring. -+ * @haystack: a C string -+ * @needle: a substring -+ * -+ * Example: -+ * assert(strcount("aaa aaa", "a") == 6); -+ * assert(strcount("aaa aaa", "ab") == 0); -+ * assert(strcount("aaa aaa", "aa") == 2); -+ */ -+size_t strcount(const char *haystack, const char *needle); -+ -+/** -+ * STR_MAX_CHARS - Maximum possible size of numeric string for this type. -+ * @type_or_expr: a pointer or integer type or expression. -+ * -+ * This provides enough space for a nul-terminated string which represents the -+ * largest possible value for the type or expression. -+ * -+ * Note: The implementation adds extra space so hex values or negative -+ * values will fit (eg. sprintf(... "%p"). ) -+ * -+ * Example: -+ * char str[STR_MAX_CHARS(int)]; -+ * -+ * sprintf(str, "%i", 7); -+ */ -+#define STR_MAX_CHARS(type_or_expr) \ -+ ((sizeof(type_or_expr) * CHAR_BIT + 8) / 9 * 3 + 2 \ -+ + STR_MAX_CHARS_TCHECK_(type_or_expr)) -+ -+#if HAVE_TYPEOF -+/* Only a simple type can have 0 assigned, so test that. */ -+#define STR_MAX_CHARS_TCHECK_(type_or_expr) \ -+ ({ typeof(type_or_expr) x = 0; (void)x; 0; }) -+#else -+#define STR_MAX_CHARS_TCHECK_(type_or_expr) 0 -+#endif -+ -+/** -+ * cisalnum - isalnum() which takes a char (and doesn't accept EOF) -+ * @c: a character -+ * -+ * Surprisingly, the standard ctype.h isalnum() takes an int, which -+ * must have the value of EOF (-1) or an unsigned char. This variant -+ * takes a real char, and doesn't accept EOF. -+ */ -+static inline bool cisalnum(char c) -+{ -+ return isalnum((unsigned char)c); -+} -+static inline bool cisalpha(char c) -+{ -+ return isalpha((unsigned char)c); -+} -+static inline bool cisascii(char c) -+{ -+ return isascii((unsigned char)c); -+} -+#if HAVE_ISBLANK -+static inline bool cisblank(char c) -+{ -+ return isblank((unsigned char)c); -+} -+#endif -+static inline bool ciscntrl(char c) -+{ -+ return iscntrl((unsigned char)c); -+} -+static inline bool cisdigit(char c) -+{ -+ return isdigit((unsigned char)c); -+} -+static inline bool cisgraph(char c) -+{ -+ return isgraph((unsigned char)c); -+} -+static inline bool cislower(char c) -+{ -+ return islower((unsigned char)c); -+} -+static inline bool cisprint(char c) -+{ -+ return isprint((unsigned char)c); -+} -+static inline bool cispunct(char c) -+{ -+ return ispunct((unsigned char)c); -+} -+static inline bool cisspace(char c) -+{ -+ return isspace((unsigned char)c); -+} -+static inline bool cisupper(char c) -+{ -+ return isupper((unsigned char)c); -+} -+static inline bool cisxdigit(char c) -+{ -+ return isxdigit((unsigned char)c); -+} -+ -+#include -+ -+/* These checks force things out of line, hence they are under DEBUG. */ -+#ifdef CCAN_STR_DEBUG -+#include -+ -+/* These are commonly misused: they take -1 or an *unsigned* char value. */ -+#undef isalnum -+#undef isalpha -+#undef isascii -+#undef isblank -+#undef iscntrl -+#undef isdigit -+#undef isgraph -+#undef islower -+#undef isprint -+#undef ispunct -+#undef isspace -+#undef isupper -+#undef isxdigit -+ -+/* You can use a char if char is unsigned. */ -+#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF -+#define str_check_arg_(i) \ -+ ((i) + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(i), \ -+ char) \ -+ || (char)255 > 0)) -+#else -+#define str_check_arg_(i) (i) -+#endif -+ -+#define isalnum(i) str_isalnum(str_check_arg_(i)) -+#define isalpha(i) str_isalpha(str_check_arg_(i)) -+#define isascii(i) str_isascii(str_check_arg_(i)) -+#if HAVE_ISBLANK -+#define isblank(i) str_isblank(str_check_arg_(i)) -+#endif -+#define iscntrl(i) str_iscntrl(str_check_arg_(i)) -+#define isdigit(i) str_isdigit(str_check_arg_(i)) -+#define isgraph(i) str_isgraph(str_check_arg_(i)) -+#define islower(i) str_islower(str_check_arg_(i)) -+#define isprint(i) str_isprint(str_check_arg_(i)) -+#define ispunct(i) str_ispunct(str_check_arg_(i)) -+#define isspace(i) str_isspace(str_check_arg_(i)) -+#define isupper(i) str_isupper(str_check_arg_(i)) -+#define isxdigit(i) str_isxdigit(str_check_arg_(i)) -+ -+#if HAVE_TYPEOF -+/* With GNU magic, we can make const-respecting standard string functions. */ -+#undef strstr -+#undef strchr -+#undef strrchr -+ -+/* + 0 is needed to decay array into pointer. */ -+#define strstr(haystack, needle) \ -+ ((typeof((haystack) + 0))str_strstr((haystack), (needle))) -+#define strchr(haystack, c) \ -+ ((typeof((haystack) + 0))str_strchr((haystack), (c))) -+#define strrchr(haystack, c) \ -+ ((typeof((haystack) + 0))str_strrchr((haystack), (c))) -+#endif -+#endif /* CCAN_STR_DEBUG */ -+ -+#endif /* CCAN_STR_H */ -diff --git a/src/rc-compat/v37/ccan/str_debug.h b/src/rc-compat/v37/ccan/str_debug.h -new file mode 100644 -index 000000000000..7a3343816f7f ---- /dev/null -+++ b/src/rc-compat/v37/ccan/str_debug.h -@@ -0,0 +1,30 @@ -+/* CC0 (Public domain) - see LICENSE.CC0 file for details */ -+#ifndef CCAN_STR_DEBUG_H -+#define CCAN_STR_DEBUG_H -+ -+/* #define CCAN_STR_DEBUG 1 */ -+ -+#ifdef CCAN_STR_DEBUG -+/* Because we mug the real ones with macros, we need our own wrappers. */ -+int str_isalnum(int i); -+int str_isalpha(int i); -+int str_isascii(int i); -+#if HAVE_ISBLANK -+int str_isblank(int i); -+#endif -+int str_iscntrl(int i); -+int str_isdigit(int i); -+int str_isgraph(int i); -+int str_islower(int i); -+int str_isprint(int i); -+int str_ispunct(int i); -+int str_isspace(int i); -+int str_isupper(int i); -+int str_isxdigit(int i); -+ -+char *str_strstr(const char *haystack, const char *needle); -+char *str_strchr(const char *s, int c); -+char *str_strrchr(const char *s, int c); -+#endif /* CCAN_STR_DEBUG */ -+ -+#endif /* CCAN_STR_DEBUG_H */ -diff --git a/src/rc-compat/v37/cmd_ioctl.h b/src/rc-compat/v37/cmd_ioctl.h -new file mode 100644 -index 000000000000..d5889a16ecc3 ---- /dev/null -+++ b/src/rc-compat/v37/cmd_ioctl.h -@@ -0,0 +1,412 @@ -+/* -+ * Copyright (c) 2018 Mellanox Technologies, Ltd. 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. -+ */ -+ -+#ifndef __INFINIBAND_VERBS_IOCTL_H -+#define __INFINIBAND_VERBS_IOCTL_H -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static inline uint64_t ioctl_ptr_to_u64(const void *ptr) -+{ -+ if (sizeof(ptr) == sizeof(uint64_t)) -+ return (uintptr_t)ptr; -+ -+ /* -+ * Some CPU architectures require sign extension when converting from -+ * a 32 bit to 64 bit pointer. This should match the kernel -+ * implementation of compat_ptr() for the architecture. -+ */ -+#if defined(__tilegx__) -+ return (int64_t)(intptr_t)ptr; -+#else -+ return (uintptr_t)ptr; -+#endif -+} -+ -+static inline void _scrub_ptr_attr(void **ptr) -+{ -+#if UINTPTR_MAX == UINT64_MAX -+ /* Do nothing */ -+#else -+ RDMA_UAPI_PTR(void *, data) *scrub_data; -+ -+ scrub_data = container_of(ptr, typeof(*scrub_data), data); -+ scrub_data->data_data_u64 = ioctl_ptr_to_u64(scrub_data->data); -+#endif -+} -+ -+#define scrub_ptr_attr(ptr) _scrub_ptr_attr((void **)(&ptr)) -+ -+/* -+ * The command buffer is organized as a linked list of blocks of attributes. -+ * Each stack frame allocates its block and then calls up toward to core code -+ * which will do the ioctl. The frame that does the ioctl calls the special -+ * FINAL variant which will allocate enough space to linearize the attribute -+ * buffer for the kernel. -+ * -+ * The current range of attributes to fill is next_attr -> last_attr. -+ */ -+struct ibv_command_buffer { -+ struct ibv_command_buffer *next; -+ struct ib_uverbs_attr *next_attr; -+ struct ib_uverbs_attr *last_attr; -+ /* -+ * Used by the legacy write interface to keep track of where the UHW -+ * buffer is located and the 'headroom' space that the common code -+ * uses to construct the command header and common command struct -+ * directly before the drivers' UHW. -+ */ -+ uint8_t uhw_in_idx; -+ uint8_t uhw_out_idx; -+ uint8_t uhw_in_headroom_dwords; -+ uint8_t uhw_out_headroom_dwords; -+ -+ uint8_t buffer_error:1; -+ /* -+ * These flags control what execute_ioctl_fallback does if the kernel -+ * does not support ioctl -+ */ -+ uint8_t fallback_require_ex:1; -+ uint8_t fallback_ioctl_only:1; -+ struct ib_uverbs_ioctl_hdr hdr; -+}; -+ -+enum {_UHW_NO_INDEX = 0xFF}; -+ -+/* -+ * Constructing an array of ibv_command_buffer is a reasonable way to expand -+ * the VLA in hdr.attrs on the stack and also allocate some internal state in -+ * a single contiguous stack memory region. It will over-allocate the region in -+ * some cases, but this approach allows the number of elements to be dynamic, -+ * and not fixed as a compile time constant. -+ */ -+#define _IOCTL_NUM_CMDB(_num_attrs) \ -+ ((sizeof(struct ibv_command_buffer) + \ -+ sizeof(struct ib_uverbs_attr) * (_num_attrs) + \ -+ sizeof(struct ibv_command_buffer) - 1) / \ -+ sizeof(struct ibv_command_buffer)) -+ -+unsigned int __ioctl_final_num_attrs(unsigned int num_attrs, -+ struct ibv_command_buffer *link); -+ -+/* If the user doesn't provide a link then don't create a VLA */ -+#define _ioctl_final_num_attrs(_num_attrs, _link) \ -+ ((__builtin_constant_p(!(_link)) && !(_link)) \ -+ ? (_num_attrs) \ -+ : __ioctl_final_num_attrs(_num_attrs, _link)) -+ -+#define _COMMAND_BUFFER_INIT(_hdr, _object_id, _method_id, _num_attrs, _link) \ -+ ((struct ibv_command_buffer){ \ -+ .hdr = \ -+ { \ -+ .object_id = (_object_id), \ -+ .method_id = (_method_id), \ -+ }, \ -+ .next = _link, \ -+ .uhw_in_idx = _UHW_NO_INDEX, \ -+ .uhw_out_idx = _UHW_NO_INDEX, \ -+ .next_attr = (_hdr).attrs, \ -+ .last_attr = (_hdr).attrs + _num_attrs}) -+ -+/* -+ * C99 does not permit an initializer for VLAs, so this function does the init -+ * instead. It is called in the wonky way so that DELCARE_COMMAND_BUFFER can -+ * still be a 'variable', and we so we don't require C11 mode. -+ */ -+static inline int _ioctl_init_cmdb(struct ibv_command_buffer *cmd, -+ uint16_t object_id, uint16_t method_id, -+ size_t num_attrs, -+ struct ibv_command_buffer *link) -+{ -+ *cmd = _COMMAND_BUFFER_INIT(cmd->hdr, object_id, method_id, num_attrs, -+ link); -+ return 0; -+} -+ -+/* -+ * Construct an IOCTL command buffer on the stack with enough space for -+ * _num_attrs elements. _num_attrs does not have to be a compile time constant. -+ * _link is a previous COMMAND_BUFFER in the call chain. -+ */ -+#ifndef __CHECKER__ -+#define DECLARE_COMMAND_BUFFER_LINK(_name, _object_id, _method_id, _num_attrs, \ -+ _link) \ -+ const unsigned int __##_name##total = \ -+ _ioctl_final_num_attrs(_num_attrs, _link); \ -+ struct ibv_command_buffer _name[_IOCTL_NUM_CMDB(__##_name##total)]; \ -+ int __attribute__((unused)) __##_name##dummy = _ioctl_init_cmdb( \ -+ _name, _object_id, _method_id, __##_name##total, _link) -+#else -+/* -+ * sparse enforces kernel rules which forbids VLAs. Make the VLA into a static -+ * array when running sparse. Don't actually run the sparse compile result. -+ */ -+#define DECLARE_COMMAND_BUFFER_LINK(_name, _object_id, _method_id, _num_attrs, \ -+ _link) \ -+ struct ibv_command_buffer _name[10]; \ -+ int __attribute__((unused)) __##_name##dummy = \ -+ _ioctl_init_cmdb(_name, _object_id, _method_id, 10, _link) -+#endif -+ -+#define DECLARE_COMMAND_BUFFER(_name, _object_id, _method_id, _num_attrs) \ -+ DECLARE_COMMAND_BUFFER_LINK(_name, _object_id, _method_id, _num_attrs, \ -+ NULL) -+ -+int execute_ioctl(struct ibv_context *context, struct ibv_command_buffer *cmd); -+ -+static inline struct ib_uverbs_attr * -+_ioctl_next_attr(struct ibv_command_buffer *cmd, uint16_t attr_id) -+{ -+ struct ib_uverbs_attr *attr; -+ -+ assert(cmd->next_attr < cmd->last_attr); -+ attr = cmd->next_attr++; -+ -+ *attr = (struct ib_uverbs_attr){ -+ .attr_id = attr_id, -+ /* -+ * All attributes default to mandatory. Wrapper the fill_* -+ * call in attr_optional() to make it optional. -+ */ -+ .flags = UVERBS_ATTR_F_MANDATORY, -+ }; -+ -+ return attr; -+} -+ -+/* -+ * This construction is insane, an expression with a side effect that returns -+ * from the calling function, but it is a non-invasive way to get the compiler -+ * to elide the IOCTL support in the backwards compat command functions -+ * without disturbing native ioctl support. -+ * -+ * A command function will set last_attr on the stack to NULL, and if it is -+ * coded properly, the compiler will prove that last_attr is never changed and -+ * elide the function. Unfortunately this penalizes native ioctl uses with the -+ * extra if overhead. -+ * -+ * For this reason, _ioctl_next_attr must never be called outside a fill -+ * function. -+ */ -+#if VERBS_WRITE_ONLY -+#define _ioctl_next_attr(cmd, attr_id) \ -+ ({ \ -+ if (!((cmd)->last_attr)) \ -+ return NULL; \ -+ _ioctl_next_attr(cmd, attr_id); \ -+ }) -+#endif -+ -+/* Make the attribute optional. */ -+static inline struct ib_uverbs_attr *attr_optional(struct ib_uverbs_attr *attr) -+{ -+ if (!attr) -+ return attr; -+ -+ attr->flags &= ~UVERBS_ATTR_F_MANDATORY; -+ return attr; -+} -+ -+/* Send attributes of kernel type UVERBS_ATTR_TYPE_IDR */ -+static inline struct ib_uverbs_attr * -+fill_attr_in_obj(struct ibv_command_buffer *cmd, uint16_t attr_id, uint32_t idr) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ /* UVERBS_ATTR_TYPE_IDR uses a 64 bit value for the idr # */ -+ attr->data = idr; -+ return attr; -+} -+ -+static inline struct ib_uverbs_attr * -+fill_attr_out_obj(struct ibv_command_buffer *cmd, uint16_t attr_id) -+{ -+ return fill_attr_in_obj(cmd, attr_id, 0); -+} -+ -+static inline uint32_t read_attr_obj(uint16_t attr_id, -+ struct ib_uverbs_attr *attr) -+{ -+ assert(attr->attr_id == attr_id); -+ return attr->data; -+} -+ -+/* Send attributes of kernel type UVERBS_ATTR_TYPE_PTR_IN */ -+static inline struct ib_uverbs_attr * -+fill_attr_in(struct ibv_command_buffer *cmd, uint16_t attr_id, const void *data, -+ size_t len) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ if (unlikely(len > UINT16_MAX)) -+ cmd->buffer_error = 1; -+ -+ attr->len = len; -+ if (len <= sizeof(uint64_t)) -+ memcpy(&attr->data, data, len); -+ else -+ attr->data = ioctl_ptr_to_u64(data); -+ -+ return attr; -+} -+ -+#define fill_attr_in_ptr(cmd, attr_id, ptr) \ -+ fill_attr_in(cmd, attr_id, ptr, sizeof(*ptr)) -+ -+/* Send attributes of various inline kernel types */ -+ -+static inline struct ib_uverbs_attr * -+fill_attr_in_uint64(struct ibv_command_buffer *cmd, uint16_t attr_id, -+ uint64_t data) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ attr->len = sizeof(data); -+ attr->data = data; -+ -+ return attr; -+} -+ -+#define fill_attr_const_in(cmd, attr_id, _data) \ -+ fill_attr_in_uint64(cmd, attr_id, _data) -+ -+static inline struct ib_uverbs_attr * -+fill_attr_in_uint32(struct ibv_command_buffer *cmd, uint16_t attr_id, -+ uint32_t data) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ attr->len = sizeof(data); -+ memcpy(&attr->data, &data, sizeof(data)); -+ -+ return attr; -+} -+ -+static inline struct ib_uverbs_attr * -+fill_attr_in_fd(struct ibv_command_buffer *cmd, uint16_t attr_id, int fd) -+{ -+ struct ib_uverbs_attr *attr; -+ -+ if (fd == -1) -+ return NULL; -+ -+ attr = _ioctl_next_attr(cmd, attr_id); -+ /* UVERBS_ATTR_TYPE_FD uses a 64 bit value for the idr # */ -+ attr->data = fd; -+ return attr; -+} -+ -+static inline struct ib_uverbs_attr * -+fill_attr_out_fd(struct ibv_command_buffer *cmd, uint16_t attr_id, int fd) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ attr->data = 0; -+ return attr; -+} -+ -+static inline int read_attr_fd(uint16_t attr_id, struct ib_uverbs_attr *attr) -+{ -+ assert(attr->attr_id == attr_id); -+ /* The kernel cannot fail to create a FD here, it never returns -1 */ -+ return attr->data; -+} -+ -+/* Send attributes of kernel type UVERBS_ATTR_TYPE_PTR_OUT */ -+static inline struct ib_uverbs_attr * -+fill_attr_out(struct ibv_command_buffer *cmd, uint16_t attr_id, void *data, -+ size_t len) -+{ -+ struct ib_uverbs_attr *attr = _ioctl_next_attr(cmd, attr_id); -+ -+ if (unlikely(len > UINT16_MAX)) -+ cmd->buffer_error = 1; -+ -+ attr->len = len; -+ attr->data = ioctl_ptr_to_u64(data); -+ -+ return attr; -+} -+ -+#define fill_attr_out_ptr(cmd, attr_id, ptr) \ -+ fill_attr_out(cmd, attr_id, ptr, sizeof(*(ptr))) -+ -+/* If size*nelems overflows size_t this returns SIZE_MAX */ -+static inline size_t _array_len(size_t size, size_t nelems) -+{ -+ if (size != 0 && -+ SIZE_MAX / size <= nelems) -+ return SIZE_MAX; -+ return size * nelems; -+} -+ -+#define fill_attr_out_ptr_array(cmd, attr_id, ptr, nelems) \ -+ fill_attr_out(cmd, attr_id, ptr, _array_len(sizeof(*ptr), nelems)) -+ -+#define fill_attr_in_ptr_array(cmd, attr_id, ptr, nelems) \ -+ fill_attr_in(cmd, attr_id, ptr, _array_len(sizeof(*ptr), nelems)) -+ -+static inline size_t __check_divide(size_t val, unsigned int div) -+{ -+ assert(val % div == 0); -+ return val / div; -+} -+ -+static inline struct ib_uverbs_attr * -+fill_attr_in_enum(struct ibv_command_buffer *cmd, uint16_t attr_id, -+ uint8_t elem_id, const void *data, size_t len) -+{ -+ struct ib_uverbs_attr *attr; -+ -+ attr = fill_attr_in(cmd, attr_id, data, len); -+ attr->attr_data.enum_data.elem_id = elem_id; -+ -+ return attr; -+} -+ -+/* Send attributes of kernel type UVERBS_ATTR_TYPE_IDRS_ARRAY */ -+static inline struct ib_uverbs_attr * -+fill_attr_in_objs_arr(struct ibv_command_buffer *cmd, uint16_t attr_id, -+ const uint32_t *idrs_arr, size_t nelems) -+{ -+ return fill_attr_in(cmd, attr_id, idrs_arr, -+ _array_len(sizeof(*idrs_arr), nelems)); -+} -+ -+#endif -diff --git a/src/rc-compat/v37/config.h b/src/rc-compat/v37/config.h -new file mode 100644 -index 000000000000..4a63336a8a0d ---- /dev/null -+++ b/src/rc-compat/v37/config.h -@@ -0,0 +1,56 @@ -+#ifndef CONFIG_H_IN -+#define CONFIG_H_IN -+ -+#define HAVE_STATEMENT_EXPR 1 -+#define HAVE_BUILTIN_TYPES_COMPATIBLE_P 1 -+#define HAVE_TYPEOF 1 -+#define HAVE_ISBLANK 1 -+#define HAVE_BUILTIN_CLZ 1 -+#define HAVE_BUILTIN_CLZL 1 -+ -+//#define PACKAGE_VERSION "37.3" -+ -+// FIXME: Remove this, The cmake version hard-requires new style CLOEXEC support -+#define STREAM_CLOEXEC "e" -+ -+#define RDMA_CDEV_DIR "/dev/infiniband" -+ -+#define VERBS_PROVIDER_SUFFIX "-rdmav34.so" -+#define IBVERBS_PABI_VERSION 34 -+ -+// FIXME This has been supported in compilers forever, we should just fail to build on such old systems. -+#define HAVE_FUNC_ATTRIBUTE_ALWAYS_INLINE 1 -+ -+#define HAVE_FUNC_ATTRIBUTE_IFUNC 1 -+ -+/* #undef HAVE_FUNC_ATTRIBUTE_SYMVER */ -+ -+#define HAVE_WORKING_IF_H 1 -+ -+// Operating mode for symbol versions -+#define HAVE_FULL_SYMBOL_VERSIONS 1 -+/* #undef HAVE_LIMITED_SYMBOL_VERSIONS */ -+ -+#define SIZEOF_LONG 8 -+ -+#if 3 == 1 -+# define VERBS_IOCTL_ONLY 1 -+# define VERBS_WRITE_ONLY 0 -+#elif 3 == 2 -+# define VERBS_IOCTL_ONLY 0 -+# define VERBS_WRITE_ONLY 1 -+#elif 3 == 3 -+# define VERBS_IOCTL_ONLY 0 -+# define VERBS_WRITE_ONLY 0 -+#endif -+ -+// Configuration defaults -+ -+#define IBACM_SERVER_MODE_UNIX 0 -+#define IBACM_SERVER_MODE_LOOP 1 -+#define IBACM_SERVER_MODE_OPEN 2 -+#define IBACM_SERVER_MODE_DEFAULT IBACM_SERVER_MODE_UNIX -+ -+#define IBACM_ACME_PLUS_KERNEL_ONLY_DEFAULT 0 -+ -+#endif -diff --git a/src/rc-compat/v37/driver.h b/src/rc-compat/v37/driver.h -new file mode 100644 -index 000000000000..46406cc433f6 ---- /dev/null -+++ b/src/rc-compat/v37/driver.h -@@ -0,0 +1,755 @@ -+/* -+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. -+ * Copyright (c) 2005, 2006 Cisco Systems, Inc. All rights reserved. -+ * Copyright (c) 2005 PathScale, Inc. All rights reserved. -+ * Copyright (c) 2020 Intel 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. -+ */ -+ -+#ifndef INFINIBAND_DRIVER_H -+#define INFINIBAND_DRIVER_H -+ -+#include -+#include -+#include "kern-abi.h" -+#include "cmd_ioctl.h" -+#include -+#include "config.h" -+#include -+#include -+#include "cmd_ioctl.h" -+#include -+ -+/* NOTE: Start of StarlingX addition */ -+#define IBV_DEVICE_LIBRARY_EXTENSION rdmav34 -+/* NOTE: End of StarlingX addition */ -+ -+struct verbs_device; -+ -+enum { -+ VERBS_LOG_LEVEL_NONE, -+ VERBS_LOG_ERR, -+ VERBS_LOG_WARN, -+ VERBS_LOG_INFO, -+ VERBS_LOG_DEBUG, -+}; -+ -+void __verbs_log(struct verbs_context *ctx, uint32_t level, -+ const char *fmt, ...); -+ -+#define verbs_log(ctx, level, format, arg...) \ -+do { \ -+ int tmp = errno; \ -+ __verbs_log(ctx, level, "%s: %s:%d: " format, \ -+ (ctx)->context.device->name, __func__, __LINE__, ##arg); \ -+ errno = tmp; \ -+} while (0) -+ -+#define verbs_debug(ctx, format, arg...) \ -+ verbs_log(ctx, VERBS_LOG_DEBUG, format, ##arg) -+ -+#define verbs_info(ctx, format, arg...) \ -+ verbs_log(ctx, VERBS_LOG_INFO, format, ##arg) -+ -+#define verbs_warn(ctx, format, arg...) \ -+ verbs_log(ctx, VERBS_LOG_WARN, format, ##arg) -+ -+#define verbs_err(ctx, format, arg...) \ -+ verbs_log(ctx, VERBS_LOG_ERR, format, ##arg) -+ -+#ifdef VERBS_DEBUG -+#define verbs_log_datapath(ctx, level, format, arg...) \ -+ verbs_log(ctx, level, format, ##arg) -+#else -+#define verbs_log_datapath(ctx, level, format, arg...) {} -+#endif -+ -+#define verbs_debug_datapath(ctx, format, arg...) \ -+ verbs_log_datapath(ctx, VERBS_LOG_DEBUG, format, ##arg) -+ -+#define verbs_info_datapath(ctx, format, arg...) \ -+ verbs_log_datapath(ctx, VERBS_LOG_INFO, format, ##arg) -+ -+#define verbs_warn_datapath(ctx, format, arg...) \ -+ verbs_log_datapath(ctx, VERBS_LOG_WARN, format, ##arg) -+ -+#define verbs_err_datapath(ctx, format, arg...) \ -+ verbs_log_datapath(ctx, VERBS_LOG_ERR, format, ##arg) -+ -+enum verbs_xrcd_mask { -+ VERBS_XRCD_HANDLE = 1 << 0, -+ VERBS_XRCD_RESERVED = 1 << 1 -+}; -+ -+enum create_cq_cmd_flags { -+ CREATE_CQ_CMD_FLAGS_TS_IGNORED_EX = 1 << 0, -+}; -+ -+struct verbs_xrcd { -+ struct ibv_xrcd xrcd; -+ uint32_t comp_mask; -+ uint32_t handle; -+}; -+ -+struct verbs_srq { -+ struct ibv_srq srq; -+ enum ibv_srq_type srq_type; -+ struct verbs_xrcd *xrcd; -+ struct ibv_cq *cq; -+ uint32_t srq_num; -+}; -+ -+enum verbs_qp_mask { -+ VERBS_QP_XRCD = 1 << 0, -+ VERBS_QP_EX = 1 << 1, -+}; -+ -+enum ibv_gid_type_sysfs { -+ IBV_GID_TYPE_SYSFS_IB_ROCE_V1, -+ IBV_GID_TYPE_SYSFS_ROCE_V2, -+}; -+ -+enum verbs_query_gid_attr_mask { -+ VERBS_QUERY_GID_ATTR_GID = 1 << 0, -+ VERBS_QUERY_GID_ATTR_TYPE = 1 << 1, -+ VERBS_QUERY_GID_ATTR_NDEV_IFINDEX = 1 << 2, -+}; -+ -+enum ibv_mr_type { -+ IBV_MR_TYPE_MR, -+ IBV_MR_TYPE_NULL_MR, -+ IBV_MR_TYPE_IMPORTED_MR, -+ IBV_MR_TYPE_DMABUF_MR, -+}; -+ -+struct verbs_mr { -+ struct ibv_mr ibv_mr; -+ enum ibv_mr_type mr_type; -+ int access; -+}; -+ -+static inline struct verbs_mr *verbs_get_mr(struct ibv_mr *mr) -+{ -+ return container_of(mr, struct verbs_mr, ibv_mr); -+} -+ -+struct verbs_qp { -+ union { -+ struct ibv_qp qp; -+ struct ibv_qp_ex qp_ex; -+ }; -+ uint32_t comp_mask; -+ struct verbs_xrcd *xrcd; -+}; -+static_assert(offsetof(struct ibv_qp_ex, qp_base) == 0, "Invalid qp layout"); -+ -+struct verbs_cq { -+ union { -+ struct ibv_cq cq; -+ struct ibv_cq_ex cq_ex; -+ }; -+}; -+ -+enum ibv_flow_action_type { -+ IBV_FLOW_ACTION_UNSPECIFIED, -+ IBV_FLOW_ACTION_ESP = 1, -+}; -+ -+struct verbs_flow_action { -+ struct ibv_flow_action action; -+ uint32_t handle; -+ enum ibv_flow_action_type type; -+}; -+ -+struct verbs_dm { -+ struct ibv_dm dm; -+ uint32_t handle; -+}; -+ -+enum { -+ VERBS_MATCH_SENTINEL = 0, -+ VERBS_MATCH_PCI = 1, -+ VERBS_MATCH_MODALIAS = 2, -+ VERBS_MATCH_DRIVER_ID = 3, -+}; -+ -+struct verbs_match_ent { -+ void *driver_data; -+ union { -+ const char *modalias; -+ uint64_t driver_id; -+ } u; -+ uint16_t vendor; -+ uint16_t device; -+ uint8_t kind; -+}; -+#define VERBS_DRIVER_ID(_id) \ -+ { \ -+ .u.driver_id = (_id), .kind = VERBS_MATCH_DRIVER_ID, \ -+ } -+/* Note: New drivers should only use VERBS_DRIVER_ID, the below are for legacy -+ * drivers -+ */ -+#define VERBS_PCI_MATCH(_vendor, _device, _data) \ -+ { \ -+ .driver_data = (void *)(_data), \ -+ .vendor = (_vendor), \ -+ .device = (_device), \ -+ .kind = VERBS_MATCH_PCI, \ -+ } -+ -+#define VERBS_MODALIAS_MATCH(_mod_str, _data) \ -+ { \ -+ .driver_data = (void *)(_data), \ -+ .u.modalias = (_mod_str), \ -+ .kind = VERBS_MATCH_MODALIAS, \ -+ } -+ -+/* Matching on the IB device name is STRONGLY discouraged. This will only -+ * match if there is no device/modalias file available, and it will eventually -+ * be disabled entirely if the kernel supports renaming. Use is strongly -+ * discouraged. -+ */ -+#define VERBS_NAME_MATCH(_name_prefix, _data) \ -+ { \ -+ .driver_data = (_data), \ -+ .u.modalias = "rdma_device:*N" _name_prefix "*", \ -+ .kind = VERBS_MATCH_MODALIAS, \ -+ } -+ -+enum { -+ VSYSFS_READ_MODALIAS = 1 << 0, -+ VSYSFS_READ_NODE_GUID = 1 << 1, -+}; -+ -+/* An rdma device detected in sysfs */ -+struct verbs_sysfs_dev { -+ struct list_node entry; -+ void *provider_data; -+ const struct verbs_match_ent *match; -+ unsigned int flags; -+ char sysfs_name[IBV_SYSFS_NAME_MAX]; -+ dev_t sysfs_cdev; -+ char ibdev_name[IBV_SYSFS_NAME_MAX]; -+ char ibdev_path[IBV_SYSFS_PATH_MAX]; -+ char modalias[512]; -+ uint64_t node_guid; -+ uint32_t driver_id; -+ enum ibv_node_type node_type; -+ int ibdev_idx; -+ uint32_t num_ports; -+ uint32_t abi_ver; -+ struct timespec time_created; -+}; -+ -+/* Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed */ -+struct verbs_device_ops { -+ const char *name; -+ -+ uint32_t match_min_abi_version; -+ uint32_t match_max_abi_version; -+ const struct verbs_match_ent *match_table; -+ const struct verbs_device_ops **static_providers; -+ -+ bool (*match_device)(struct verbs_sysfs_dev *sysfs_dev); -+ -+ struct verbs_context *(*alloc_context)(struct ibv_device *device, -+ int cmd_fd, -+ void *private_data); -+ struct verbs_context *(*import_context)(struct ibv_device *device, -+ int cmd_fd); -+ -+ struct verbs_device *(*alloc_device)(struct verbs_sysfs_dev *sysfs_dev); -+ void (*uninit_device)(struct verbs_device *device); -+}; -+ -+/* Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed */ -+struct verbs_device { -+ struct ibv_device device; /* Must be first */ -+ const struct verbs_device_ops *ops; -+ atomic_int refcount; -+ struct list_node entry; -+ struct verbs_sysfs_dev *sysfs; -+ uint64_t core_support; -+}; -+ -+struct verbs_counters { -+ struct ibv_counters counters; -+ uint32_t handle; -+}; -+ -+/* -+ * Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed. This is -+ * the union of every op the driver can support. If new elements are added to -+ * this structure then verbs_dummy_ops must also be updated. -+ * -+ * Keep sorted. -+ */ -+struct verbs_context_ops { -+ 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_dm *(*alloc_dm)(struct ibv_context *context, -+ struct ibv_alloc_dm_attr *attr); -+ struct ibv_mw *(*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); -+ struct ibv_mr *(*alloc_null_mr)(struct ibv_pd *pd); -+ struct ibv_pd *(*alloc_parent_domain)( -+ struct ibv_context *context, -+ struct ibv_parent_domain_init_attr *attr); -+ struct ibv_pd *(*alloc_pd)(struct ibv_context *context); -+ struct ibv_td *(*alloc_td)(struct ibv_context *context, -+ struct ibv_td_init_attr *init_attr); -+ void (*async_event)(struct ibv_context *context, struct ibv_async_event *event); -+ int (*attach_counters_point_flow)(struct ibv_counters *counters, -+ struct ibv_counter_attach_attr *attr, -+ struct ibv_flow *flow); -+ int (*attach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -+ uint16_t lid); -+ int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, -+ struct ibv_mw_bind *mw_bind); -+ int (*close_xrcd)(struct ibv_xrcd *xrcd); -+ void (*cq_event)(struct ibv_cq *cq); -+ struct ibv_ah *(*create_ah)(struct ibv_pd *pd, -+ struct ibv_ah_attr *attr); -+ struct ibv_counters *(*create_counters)(struct ibv_context *context, -+ struct ibv_counters_init_attr *init_attr); -+ struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, -+ struct ibv_comp_channel *channel, -+ int comp_vector); -+ struct ibv_cq_ex *(*create_cq_ex)( -+ struct ibv_context *context, -+ struct ibv_cq_init_attr_ex *init_attr); -+ struct ibv_flow *(*create_flow)(struct ibv_qp *qp, -+ struct ibv_flow_attr *flow_attr); -+ struct ibv_flow_action *(*create_flow_action_esp)(struct ibv_context *context, -+ struct ibv_flow_action_esp_attr *attr); -+ struct ibv_qp *(*create_qp)(struct ibv_pd *pd, -+ struct ibv_qp_init_attr *attr); -+ struct ibv_qp *(*create_qp_ex)( -+ struct ibv_context *context, -+ struct ibv_qp_init_attr_ex *qp_init_attr_ex); -+ struct ibv_rwq_ind_table *(*create_rwq_ind_table)( -+ struct ibv_context *context, -+ struct ibv_rwq_ind_table_init_attr *init_attr); -+ struct ibv_srq *(*create_srq)(struct ibv_pd *pd, -+ struct ibv_srq_init_attr *srq_init_attr); -+ struct ibv_srq *(*create_srq_ex)( -+ struct ibv_context *context, -+ struct ibv_srq_init_attr_ex *srq_init_attr_ex); -+ struct ibv_wq *(*create_wq)(struct ibv_context *context, -+ struct ibv_wq_init_attr *wq_init_attr); -+ int (*dealloc_mw)(struct ibv_mw *mw); -+ int (*dealloc_pd)(struct ibv_pd *pd); -+ int (*dealloc_td)(struct ibv_td *td); -+ int (*dereg_mr)(struct verbs_mr *vmr); -+ int (*destroy_ah)(struct ibv_ah *ah); -+ int (*destroy_counters)(struct ibv_counters *counters); -+ int (*destroy_cq)(struct ibv_cq *cq); -+ int (*destroy_flow)(struct ibv_flow *flow); -+ int (*destroy_flow_action)(struct ibv_flow_action *action); -+ int (*destroy_qp)(struct ibv_qp *qp); -+ int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); -+ int (*destroy_srq)(struct ibv_srq *srq); -+ int (*destroy_wq)(struct ibv_wq *wq); -+ int (*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -+ uint16_t lid); -+ void (*free_context)(struct ibv_context *context); -+ int (*free_dm)(struct ibv_dm *dm); -+ int (*get_srq_num)(struct ibv_srq *srq, uint32_t *srq_num); -+ struct ibv_dm *(*import_dm)(struct ibv_context *context, -+ uint32_t dm_handle); -+ struct ibv_mr *(*import_mr)(struct ibv_pd *pd, -+ uint32_t mr_handle); -+ struct ibv_pd *(*import_pd)(struct ibv_context *context, -+ uint32_t pd_handle); -+ int (*modify_cq)(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr); -+ int (*modify_flow_action_esp)(struct ibv_flow_action *action, -+ struct ibv_flow_action_esp_attr *attr); -+ int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask); -+ int (*modify_qp_rate_limit)(struct ibv_qp *qp, -+ struct ibv_qp_rate_limit_attr *attr); -+ int (*modify_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, -+ int srq_attr_mask); -+ int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); -+ struct ibv_qp *(*open_qp)(struct ibv_context *context, -+ struct ibv_qp_open_attr *attr); -+ struct ibv_xrcd *(*open_xrcd)( -+ struct ibv_context *context, -+ struct ibv_xrcd_init_attr *xrcd_init_attr); -+ int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); -+ 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_srq_ops)(struct ibv_srq *srq, struct ibv_ops_wr *op, -+ struct ibv_ops_wr **bad_op); -+ int (*post_srq_recv)(struct ibv_srq *srq, struct ibv_recv_wr *recv_wr, -+ struct ibv_recv_wr **bad_recv_wr); -+ int (*query_device_ex)(struct ibv_context *context, -+ const struct ibv_query_device_ex_input *input, -+ struct ibv_device_attr_ex *attr, -+ size_t attr_size); -+ int (*query_ece)(struct ibv_qp *qp, struct ibv_ece *ece); -+ int (*query_port)(struct ibv_context *context, uint8_t port_num, -+ struct ibv_port_attr *port_attr); -+ int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask, struct ibv_qp_init_attr *init_attr); -+ int (*query_qp_data_in_order)(struct ibv_qp *qp, enum ibv_wr_opcode op, -+ uint32_t flags); -+ int (*query_rt_values)(struct ibv_context *context, -+ struct ibv_values_ex *values); -+ int (*query_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr); -+ int (*read_counters)(struct ibv_counters *counters, -+ uint64_t *counters_value, -+ uint32_t ncounters, -+ uint32_t flags); -+ struct ibv_mr *(*reg_dm_mr)(struct ibv_pd *pd, struct ibv_dm *dm, -+ uint64_t dm_offset, size_t length, -+ unsigned int access); -+ struct ibv_mr *(*reg_dmabuf_mr)(struct ibv_pd *pd, uint64_t offset, -+ size_t length, uint64_t iova, -+ int fd, int access); -+ struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, -+ uint64_t hca_va, int access); -+ int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); -+ int (*rereg_mr)(struct verbs_mr *vmr, int flags, struct ibv_pd *pd, -+ void *addr, size_t length, int access); -+ int (*resize_cq)(struct ibv_cq *cq, int cqe); -+ int (*set_ece)(struct ibv_qp *qp, struct ibv_ece *ece); -+ void (*unimport_dm)(struct ibv_dm *dm); -+ void (*unimport_mr)(struct ibv_mr *mr); -+ void (*unimport_pd)(struct ibv_pd *pd); -+}; -+ -+static inline struct verbs_device * -+verbs_get_device(const struct ibv_device *dev) -+{ -+ return container_of(dev, struct verbs_device, device); -+} -+ -+typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_path, -+ int abi_version); -+ -+/* Wire the IBVERBS_PRIVATE version number into the verbs_register_driver -+ * symbol name. This guarentees we link to the correct set of symbols even if -+ * statically linking or using a dynmic linker with symbol versioning turned -+ * off. -+ */ -+#define ___make_verbs_register_driver(x) verbs_register_driver_ ## x -+#define __make_verbs_register_driver(x) ___make_verbs_register_driver(x) -+#define verbs_register_driver __make_verbs_register_driver(IBVERBS_PABI_VERSION) -+ -+void verbs_register_driver(const struct verbs_device_ops *ops); -+ -+/* -+ * Macro for providers to use to supply verbs_device_ops to the core code. -+ * This creates a global symbol for the provider structure to be used by the -+ * ibv_static_providers() machinery, and a global constructor for the dlopen -+ * machinery. -+ */ -+#define PROVIDER_DRIVER(provider_name, drv_struct) \ -+ extern const struct verbs_device_ops verbs_provider_##provider_name \ -+ __attribute__((alias(stringify(drv_struct)))); \ -+ static __attribute__((constructor)) void drv##__register_driver(void) \ -+ { \ -+ verbs_register_driver(&drv_struct); \ -+ } -+ -+void *_verbs_init_and_alloc_context(struct ibv_device *device, int cmd_fd, -+ size_t alloc_size, -+ struct verbs_context *context_offset, -+ uint32_t driver_id); -+ -+#define verbs_init_and_alloc_context(ibdev, cmd_fd, drv_ctx_ptr, ctx_memb, \ -+ driver_id) \ -+ ((typeof(drv_ctx_ptr))_verbs_init_and_alloc_context( \ -+ ibdev, cmd_fd, sizeof(*drv_ctx_ptr), \ -+ &((typeof(drv_ctx_ptr))NULL)->ctx_memb, (driver_id))) -+ -+int verbs_init_context(struct verbs_context *context_ex, -+ struct ibv_device *device, int cmd_fd, -+ uint32_t driver_id); -+void verbs_uninit_context(struct verbs_context *context); -+void verbs_set_ops(struct verbs_context *vctx, -+ const struct verbs_context_ops *ops); -+ -+void verbs_init_cq(struct ibv_cq *cq, struct ibv_context *context, -+ struct ibv_comp_channel *channel, -+ void *cq_context); -+ -+struct ibv_context *verbs_open_device(struct ibv_device *device, -+ void *private_data); -+int ibv_cmd_get_context(struct verbs_context *context, -+ struct ibv_get_context *cmd, size_t cmd_size, -+ struct ib_uverbs_get_context_resp *resp, size_t resp_size); -+int ibv_cmd_query_context(struct ibv_context *ctx, -+ struct ibv_command_buffer *driver); -+int ibv_cmd_create_flow_action_esp(struct ibv_context *ctx, -+ struct ibv_flow_action_esp_attr *attr, -+ struct verbs_flow_action *flow_action, -+ struct ibv_command_buffer *driver); -+int ibv_cmd_modify_flow_action_esp(struct verbs_flow_action *flow_action, -+ struct ibv_flow_action_esp_attr *attr, -+ struct ibv_command_buffer *driver); -+int ibv_cmd_query_device_any(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); -+int ibv_cmd_query_port(struct ibv_context *context, uint8_t port_num, -+ struct ibv_port_attr *port_attr, -+ struct ibv_query_port *cmd, size_t cmd_size); -+int ibv_cmd_alloc_async_fd(struct ibv_context *context); -+int ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd, -+ struct ibv_alloc_pd *cmd, size_t cmd_size, -+ struct ib_uverbs_alloc_pd_resp *resp, size_t resp_size); -+int ibv_cmd_dealloc_pd(struct ibv_pd *pd); -+int ibv_cmd_open_xrcd(struct ibv_context *context, struct verbs_xrcd *xrcd, -+ int vxrcd_size, -+ struct ibv_xrcd_init_attr *attr, -+ struct ibv_open_xrcd *cmd, size_t cmd_size, -+ struct ib_uverbs_open_xrcd_resp *resp, size_t resp_size); -+int ibv_cmd_close_xrcd(struct verbs_xrcd *xrcd); -+int ibv_cmd_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, -+ size_t cmd_size, -+ struct ib_uverbs_reg_mr_resp *resp, size_t resp_size); -+int ibv_cmd_rereg_mr(struct verbs_mr *vmr, uint32_t flags, void *addr, -+ size_t length, uint64_t hca_va, int access, -+ struct ibv_pd *pd, struct ibv_rereg_mr *cmd, -+ size_t cmd_sz, struct ib_uverbs_rereg_mr_resp *resp, -+ size_t resp_sz); -+int ibv_cmd_dereg_mr(struct verbs_mr *vmr); -+int ibv_cmd_query_mr(struct ibv_pd *pd, struct verbs_mr *vmr, -+ uint32_t mr_handle); -+int ibv_cmd_advise_mr(struct ibv_pd *pd, -+ enum ibv_advise_mr_advice advice, -+ uint32_t flags, -+ struct ibv_sge *sg_list, -+ uint32_t num_sge); -+int ibv_cmd_reg_dmabuf_mr(struct ibv_pd *pd, uint64_t offset, size_t length, -+ uint64_t iova, int fd, int access, -+ struct verbs_mr *vmr); -+int ibv_cmd_alloc_mw(struct ibv_pd *pd, enum ibv_mw_type type, -+ struct ibv_mw *mw, struct ibv_alloc_mw *cmd, -+ size_t cmd_size, -+ struct ib_uverbs_alloc_mw_resp *resp, size_t resp_size); -+int ibv_cmd_dealloc_mw(struct ibv_mw *mw); -+int ibv_cmd_create_cq(struct ibv_context *context, int cqe, -+ struct ibv_comp_channel *channel, -+ int comp_vector, struct ibv_cq *cq, -+ struct ibv_create_cq *cmd, size_t cmd_size, -+ struct ib_uverbs_create_cq_resp *resp, size_t resp_size); -+int ibv_cmd_create_cq_ex(struct ibv_context *context, -+ const struct ibv_cq_init_attr_ex *cq_attr, -+ struct verbs_cq *cq, -+ struct ibv_create_cq_ex *cmd, -+ size_t cmd_size, -+ struct ib_uverbs_ex_create_cq_resp *resp, -+ size_t resp_size, -+ uint32_t cmd_flags); -+int ibv_cmd_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); -+int ibv_cmd_req_notify_cq(struct ibv_cq *cq, int solicited_only); -+int ibv_cmd_resize_cq(struct ibv_cq *cq, int cqe, -+ struct ibv_resize_cq *cmd, size_t cmd_size, -+ struct ib_uverbs_resize_cq_resp *resp, size_t resp_size); -+int ibv_cmd_destroy_cq(struct ibv_cq *cq); -+int ibv_cmd_modify_cq(struct ibv_cq *cq, -+ struct ibv_modify_cq_attr *attr, -+ struct ibv_modify_cq *cmd, -+ size_t cmd_size); -+ -+int ibv_cmd_create_srq(struct ibv_pd *pd, -+ struct ibv_srq *srq, struct ibv_srq_init_attr *attr, -+ struct ibv_create_srq *cmd, size_t cmd_size, -+ struct ib_uverbs_create_srq_resp *resp, size_t resp_size); -+int ibv_cmd_create_srq_ex(struct ibv_context *context, -+ struct verbs_srq *srq, -+ struct ibv_srq_init_attr_ex *attr_ex, -+ struct ibv_create_xsrq *cmd, size_t cmd_size, -+ struct ib_uverbs_create_srq_resp *resp, size_t resp_size); -+int ibv_cmd_modify_srq(struct ibv_srq *srq, -+ struct ibv_srq_attr *srq_attr, -+ int srq_attr_mask, -+ struct ibv_modify_srq *cmd, size_t cmd_size); -+int ibv_cmd_query_srq(struct ibv_srq *srq, -+ struct ibv_srq_attr *srq_attr, -+ struct ibv_query_srq *cmd, size_t cmd_size); -+int ibv_cmd_destroy_srq(struct ibv_srq *srq); -+ -+int ibv_cmd_create_qp(struct ibv_pd *pd, -+ struct ibv_qp *qp, struct ibv_qp_init_attr *attr, -+ struct ibv_create_qp *cmd, size_t cmd_size, -+ struct ib_uverbs_create_qp_resp *resp, size_t resp_size); -+int ibv_cmd_create_qp_ex(struct ibv_context *context, -+ struct verbs_qp *qp, -+ struct ibv_qp_init_attr_ex *attr_ex, -+ struct ibv_create_qp *cmd, size_t cmd_size, -+ struct ib_uverbs_create_qp_resp *resp, size_t resp_size); -+int ibv_cmd_create_qp_ex2(struct ibv_context *context, -+ struct verbs_qp *qp, -+ struct ibv_qp_init_attr_ex *qp_attr, -+ struct ibv_create_qp_ex *cmd, -+ size_t cmd_size, -+ struct ib_uverbs_ex_create_qp_resp *resp, -+ size_t resp_size); -+int ibv_cmd_open_qp(struct ibv_context *context, -+ struct verbs_qp *qp, int vqp_sz, -+ struct ibv_qp_open_attr *attr, -+ struct ibv_open_qp *cmd, size_t cmd_size, -+ struct ib_uverbs_create_qp_resp *resp, size_t resp_size); -+int ibv_cmd_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *qp_attr, -+ int attr_mask, -+ struct ibv_qp_init_attr *qp_init_attr, -+ struct ibv_query_qp *cmd, size_t cmd_size); -+int ibv_cmd_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask, -+ struct ibv_modify_qp *cmd, size_t cmd_size); -+int ibv_cmd_modify_qp_ex(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask, struct ibv_modify_qp_ex *cmd, -+ size_t cmd_size, -+ struct ib_uverbs_ex_modify_qp_resp *resp, -+ size_t resp_size); -+int ibv_cmd_destroy_qp(struct ibv_qp *qp); -+int ibv_cmd_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, -+ struct ibv_send_wr **bad_wr); -+int ibv_cmd_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, -+ struct ibv_recv_wr **bad_wr); -+int ibv_cmd_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr, -+ struct ibv_recv_wr **bad_wr); -+int ibv_cmd_create_ah(struct ibv_pd *pd, struct ibv_ah *ah, -+ struct ibv_ah_attr *attr, -+ struct ib_uverbs_create_ah_resp *resp, -+ size_t resp_size); -+int ibv_cmd_destroy_ah(struct ibv_ah *ah); -+int ibv_cmd_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid); -+int ibv_cmd_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid); -+ -+int ibv_cmd_create_flow(struct ibv_qp *qp, -+ struct ibv_flow *flow_id, -+ struct ibv_flow_attr *flow_attr, -+ void *ucmd, -+ size_t ucmd_size); -+int ibv_cmd_destroy_flow(struct ibv_flow *flow_id); -+int ibv_cmd_create_wq(struct ibv_context *context, -+ struct ibv_wq_init_attr *wq_init_attr, -+ struct ibv_wq *wq, -+ struct ibv_create_wq *cmd, -+ size_t cmd_size, -+ struct ib_uverbs_ex_create_wq_resp *resp, -+ size_t resp_size); -+ -+int ibv_cmd_destroy_flow_action(struct verbs_flow_action *action); -+int ibv_cmd_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *attr, -+ struct ibv_modify_wq *cmd, size_t cmd_size); -+int ibv_cmd_destroy_wq(struct ibv_wq *wq); -+int ibv_cmd_create_rwq_ind_table(struct ibv_context *context, -+ struct ibv_rwq_ind_table_init_attr *init_attr, -+ struct ibv_rwq_ind_table *rwq_ind_table, -+ struct ib_uverbs_ex_create_rwq_ind_table_resp *resp, -+ size_t resp_size); -+int ibv_cmd_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table); -+int ibv_cmd_create_counters(struct ibv_context *context, -+ struct ibv_counters_init_attr *init_attr, -+ struct verbs_counters *vcounters, -+ struct ibv_command_buffer *link); -+int ibv_cmd_destroy_counters(struct verbs_counters *vcounters); -+int ibv_cmd_read_counters(struct verbs_counters *vcounters, -+ uint64_t *counters_value, -+ uint32_t ncounters, -+ uint32_t flags, -+ struct ibv_command_buffer *link); -+int ibv_dontfork_range(void *base, size_t size); -+int ibv_dofork_range(void *base, size_t size); -+int ibv_cmd_alloc_dm(struct ibv_context *ctx, -+ const struct ibv_alloc_dm_attr *dm_attr, -+ struct verbs_dm *dm, -+ struct ibv_command_buffer *link); -+int ibv_cmd_free_dm(struct verbs_dm *dm); -+int ibv_cmd_reg_dm_mr(struct ibv_pd *pd, struct verbs_dm *dm, -+ uint64_t offset, size_t length, -+ unsigned int access, struct verbs_mr *vmr, -+ struct ibv_command_buffer *link); -+ -+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 fallback_attr_mask); -+ -+/* -+ * sysfs helper functions -+ */ -+const char *ibv_get_sysfs_path(void); -+ -+int ibv_read_sysfs_file(const char *dir, const char *file, -+ char *buf, size_t size); -+int ibv_read_sysfs_file_at(int dirfd, const char *file, char *buf, size_t size); -+int ibv_read_ibdev_sysfs_file(char *buf, size_t size, -+ struct verbs_sysfs_dev *sysfs_dev, -+ const char *fnfmt, ...) -+ __attribute__((format(printf, 4, 5))); -+ -+static inline bool check_comp_mask(uint64_t input, uint64_t supported) -+{ -+ return (input & ~supported) == 0; -+} -+ -+int ibv_query_gid_type(struct ibv_context *context, uint8_t port_num, -+ unsigned int index, enum ibv_gid_type_sysfs *type); -+ -+static inline int -+ibv_check_alloc_parent_domain(struct ibv_parent_domain_init_attr *attr) -+{ -+ /* A valid protection domain must be set */ -+ if (!attr->pd) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Initialize the ibv_pd which is being used as a parent_domain. From the -+ * perspective of the core code the new ibv_pd is completely interchangeable -+ * with the passed contained_pd. -+ */ -+static inline void ibv_initialize_parent_domain(struct ibv_pd *parent_domain, -+ struct ibv_pd *contained_pd) -+{ -+ parent_domain->context = contained_pd->context; -+ parent_domain->handle = contained_pd->handle; -+} -+ -+#endif /* INFINIBAND_DRIVER_H */ -diff --git a/src/rc-compat/v37/ib_user_verbs.h b/src/rc-compat/v37/ib_user_verbs.h -new file mode 100644 -index 000000000000..7ee73a0652f1 ---- /dev/null -+++ b/src/rc-compat/v37/ib_user_verbs.h -@@ -0,0 +1,1301 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ -+/* -+ * Copyright (c) 2005 Topspin Communications. All rights reserved. -+ * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. -+ * Copyright (c) 2005 PathScale, Inc. All rights reserved. -+ * Copyright (c) 2006 Mellanox Technologies. 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. -+ */ -+ -+#ifndef IB_USER_VERBS_H -+#define IB_USER_VERBS_H -+ -+#include -+ -+/* -+ * Increment this value if any changes that break userspace ABI -+ * compatibility are made. -+ */ -+#define IB_USER_VERBS_ABI_VERSION 6 -+#define IB_USER_VERBS_CMD_THRESHOLD 50 -+ -+enum ib_uverbs_write_cmds { -+ IB_USER_VERBS_CMD_GET_CONTEXT, -+ IB_USER_VERBS_CMD_QUERY_DEVICE, -+ IB_USER_VERBS_CMD_QUERY_PORT, -+ IB_USER_VERBS_CMD_ALLOC_PD, -+ IB_USER_VERBS_CMD_DEALLOC_PD, -+ IB_USER_VERBS_CMD_CREATE_AH, -+ IB_USER_VERBS_CMD_MODIFY_AH, -+ IB_USER_VERBS_CMD_QUERY_AH, -+ IB_USER_VERBS_CMD_DESTROY_AH, -+ IB_USER_VERBS_CMD_REG_MR, -+ IB_USER_VERBS_CMD_REG_SMR, -+ IB_USER_VERBS_CMD_REREG_MR, -+ IB_USER_VERBS_CMD_QUERY_MR, -+ IB_USER_VERBS_CMD_DEREG_MR, -+ IB_USER_VERBS_CMD_ALLOC_MW, -+ IB_USER_VERBS_CMD_BIND_MW, -+ IB_USER_VERBS_CMD_DEALLOC_MW, -+ IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL, -+ IB_USER_VERBS_CMD_CREATE_CQ, -+ IB_USER_VERBS_CMD_RESIZE_CQ, -+ IB_USER_VERBS_CMD_DESTROY_CQ, -+ IB_USER_VERBS_CMD_POLL_CQ, -+ IB_USER_VERBS_CMD_PEEK_CQ, -+ IB_USER_VERBS_CMD_REQ_NOTIFY_CQ, -+ IB_USER_VERBS_CMD_CREATE_QP, -+ IB_USER_VERBS_CMD_QUERY_QP, -+ IB_USER_VERBS_CMD_MODIFY_QP, -+ IB_USER_VERBS_CMD_DESTROY_QP, -+ IB_USER_VERBS_CMD_POST_SEND, -+ IB_USER_VERBS_CMD_POST_RECV, -+ IB_USER_VERBS_CMD_ATTACH_MCAST, -+ IB_USER_VERBS_CMD_DETACH_MCAST, -+ IB_USER_VERBS_CMD_CREATE_SRQ, -+ IB_USER_VERBS_CMD_MODIFY_SRQ, -+ IB_USER_VERBS_CMD_QUERY_SRQ, -+ IB_USER_VERBS_CMD_DESTROY_SRQ, -+ IB_USER_VERBS_CMD_POST_SRQ_RECV, -+ IB_USER_VERBS_CMD_OPEN_XRCD, -+ IB_USER_VERBS_CMD_CLOSE_XRCD, -+ IB_USER_VERBS_CMD_CREATE_XSRQ, -+ IB_USER_VERBS_CMD_OPEN_QP, -+}; -+ -+enum { -+ IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE, -+ IB_USER_VERBS_EX_CMD_CREATE_CQ = IB_USER_VERBS_CMD_CREATE_CQ, -+ IB_USER_VERBS_EX_CMD_CREATE_QP = IB_USER_VERBS_CMD_CREATE_QP, -+ IB_USER_VERBS_EX_CMD_MODIFY_QP = IB_USER_VERBS_CMD_MODIFY_QP, -+ IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, -+ IB_USER_VERBS_EX_CMD_DESTROY_FLOW, -+ IB_USER_VERBS_EX_CMD_CREATE_WQ, -+ IB_USER_VERBS_EX_CMD_MODIFY_WQ, -+ IB_USER_VERBS_EX_CMD_DESTROY_WQ, -+ IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL, -+ IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL, -+ IB_USER_VERBS_EX_CMD_MODIFY_CQ -+}; -+ -+/* -+ * Make sure that all structs defined in this file remain laid out so -+ * that they pack the same way on 32-bit and 64-bit architectures (to -+ * avoid incompatibility between 32-bit userspace and 64-bit kernels). -+ * Specifically: -+ * - Do not use pointer types -- pass pointers in __u64 instead. -+ * - Make sure that any structure larger than 4 bytes is padded to a -+ * multiple of 8 bytes. Otherwise the structure size will be -+ * different between 32-bit and 64-bit architectures. -+ */ -+ -+struct ib_uverbs_async_event_desc { -+ __aligned_u64 element; -+ __u32 event_type; /* enum ib_event_type */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_comp_event_desc { -+ __aligned_u64 cq_handle; -+}; -+ -+struct ib_uverbs_cq_moderation_caps { -+ __u16 max_cq_moderation_count; -+ __u16 max_cq_moderation_period; -+ __u32 reserved; -+}; -+ -+/* -+ * All commands from userspace should start with a __u32 command field -+ * followed by __u16 in_words and out_words fields (which give the -+ * length of the command block and response buffer if any in 32-bit -+ * words). The kernel driver will read these fields first and read -+ * the rest of the command struct based on these value. -+ */ -+ -+#define IB_USER_VERBS_CMD_COMMAND_MASK 0xff -+#define IB_USER_VERBS_CMD_FLAG_EXTENDED 0x80000000u -+ -+struct ib_uverbs_cmd_hdr { -+ __u32 command; -+ __u16 in_words; -+ __u16 out_words; -+}; -+ -+struct ib_uverbs_ex_cmd_hdr { -+ __aligned_u64 response; -+ __u16 provider_in_words; -+ __u16 provider_out_words; -+ __u32 cmd_hdr_reserved; -+}; -+ -+struct ib_uverbs_get_context { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_get_context_resp { -+ __u32 async_fd; -+ __u32 num_comp_vectors; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_device { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_device_resp { -+ __aligned_u64 fw_ver; -+ __be64 node_guid; -+ __be64 sys_image_guid; -+ __aligned_u64 max_mr_size; -+ __aligned_u64 page_size_cap; -+ __u32 vendor_id; -+ __u32 vendor_part_id; -+ __u32 hw_ver; -+ __u32 max_qp; -+ __u32 max_qp_wr; -+ __u32 device_cap_flags; -+ __u32 max_sge; -+ __u32 max_sge_rd; -+ __u32 max_cq; -+ __u32 max_cqe; -+ __u32 max_mr; -+ __u32 max_pd; -+ __u32 max_qp_rd_atom; -+ __u32 max_ee_rd_atom; -+ __u32 max_res_rd_atom; -+ __u32 max_qp_init_rd_atom; -+ __u32 max_ee_init_rd_atom; -+ __u32 atomic_cap; -+ __u32 max_ee; -+ __u32 max_rdd; -+ __u32 max_mw; -+ __u32 max_raw_ipv6_qp; -+ __u32 max_raw_ethy_qp; -+ __u32 max_mcast_grp; -+ __u32 max_mcast_qp_attach; -+ __u32 max_total_mcast_qp_attach; -+ __u32 max_ah; -+ __u32 max_fmr; -+ __u32 max_map_per_fmr; -+ __u32 max_srq; -+ __u32 max_srq_wr; -+ __u32 max_srq_sge; -+ __u16 max_pkeys; -+ __u8 local_ca_ack_delay; -+ __u8 phys_port_cnt; -+ __u8 reserved[4]; -+}; -+ -+struct ib_uverbs_ex_query_device { -+ __u32 comp_mask; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_odp_caps { -+ __aligned_u64 general_caps; -+ struct { -+ __u32 rc_odp_caps; -+ __u32 uc_odp_caps; -+ __u32 ud_odp_caps; -+ } per_transport_caps; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_rss_caps { -+ /* Corresponding bit will be set if qp type from -+ * 'enum ib_qp_type' is supported, e.g. -+ * supported_qpts |= 1 << IB_QPT_UD -+ */ -+ __u32 supported_qpts; -+ __u32 max_rwq_indirection_tables; -+ __u32 max_rwq_indirection_table_size; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_tm_caps { -+ /* Max size of rendezvous request message */ -+ __u32 max_rndv_hdr_size; -+ /* Max number of entries in tag matching list */ -+ __u32 max_num_tags; -+ /* TM flags */ -+ __u32 flags; -+ /* Max number of outstanding list operations */ -+ __u32 max_ops; -+ /* Max number of SGE in tag matching entry */ -+ __u32 max_sge; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_query_device_resp { -+ struct ib_uverbs_query_device_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+ struct ib_uverbs_odp_caps odp_caps; -+ __aligned_u64 timestamp_mask; -+ __aligned_u64 hca_core_clock; /* in KHZ */ -+ __aligned_u64 device_cap_flags_ex; -+ struct ib_uverbs_rss_caps rss_caps; -+ __u32 max_wq_type_rq; -+ __u32 raw_packet_caps; -+ struct ib_uverbs_tm_caps tm_caps; -+ struct ib_uverbs_cq_moderation_caps cq_moderation_caps; -+ __aligned_u64 max_dm_size; -+ __u32 xrc_odp_caps; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_query_port { -+ __aligned_u64 response; -+ __u8 port_num; -+ __u8 reserved[7]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_port_resp { -+ __u32 port_cap_flags; /* see ib_uverbs_query_port_cap_flags */ -+ __u32 max_msg_sz; -+ __u32 bad_pkey_cntr; -+ __u32 qkey_viol_cntr; -+ __u32 gid_tbl_len; -+ __u16 pkey_tbl_len; -+ __u16 lid; -+ __u16 sm_lid; -+ __u8 state; -+ __u8 max_mtu; -+ __u8 active_mtu; -+ __u8 lmc; -+ __u8 max_vl_num; -+ __u8 sm_sl; -+ __u8 subnet_timeout; -+ __u8 init_type_reply; -+ __u8 active_width; -+ __u8 active_speed; -+ __u8 phys_state; -+ __u8 link_layer; -+ __u8 flags; /* see ib_uverbs_query_port_flags */ -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_alloc_pd { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_alloc_pd_resp { -+ __u32 pd_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_dealloc_pd { -+ __u32 pd_handle; -+}; -+ -+struct ib_uverbs_open_xrcd { -+ __aligned_u64 response; -+ __u32 fd; -+ __u32 oflags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_open_xrcd_resp { -+ __u32 xrcd_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_close_xrcd { -+ __u32 xrcd_handle; -+}; -+ -+struct ib_uverbs_reg_mr { -+ __aligned_u64 response; -+ __aligned_u64 start; -+ __aligned_u64 length; -+ __aligned_u64 hca_va; -+ __u32 pd_handle; -+ __u32 access_flags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_reg_mr_resp { -+ __u32 mr_handle; -+ __u32 lkey; -+ __u32 rkey; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_rereg_mr { -+ __aligned_u64 response; -+ __u32 mr_handle; -+ __u32 flags; -+ __aligned_u64 start; -+ __aligned_u64 length; -+ __aligned_u64 hca_va; -+ __u32 pd_handle; -+ __u32 access_flags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_rereg_mr_resp { -+ __u32 lkey; -+ __u32 rkey; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_dereg_mr { -+ __u32 mr_handle; -+}; -+ -+struct ib_uverbs_alloc_mw { -+ __aligned_u64 response; -+ __u32 pd_handle; -+ __u8 mw_type; -+ __u8 reserved[3]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_alloc_mw_resp { -+ __u32 mw_handle; -+ __u32 rkey; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_dealloc_mw { -+ __u32 mw_handle; -+}; -+ -+struct ib_uverbs_create_comp_channel { -+ __aligned_u64 response; -+}; -+ -+struct ib_uverbs_create_comp_channel_resp { -+ __u32 fd; -+}; -+ -+struct ib_uverbs_create_cq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 cqe; -+ __u32 comp_vector; -+ __s32 comp_channel; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+enum ib_uverbs_ex_create_cq_flags { -+ IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION = 1 << 0, -+ IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN = 1 << 1, -+}; -+ -+struct ib_uverbs_ex_create_cq { -+ __aligned_u64 user_handle; -+ __u32 cqe; -+ __u32 comp_vector; -+ __s32 comp_channel; -+ __u32 comp_mask; -+ __u32 flags; /* bitmask of ib_uverbs_ex_create_cq_flags */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_create_cq_resp { -+ __u32 cq_handle; -+ __u32 cqe; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_create_cq_resp { -+ struct ib_uverbs_create_cq_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+struct ib_uverbs_resize_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 cqe; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_resize_cq_resp { -+ __u32 cqe; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_poll_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 ne; -+}; -+ -+enum ib_uverbs_wc_opcode { -+ IB_UVERBS_WC_SEND = 0, -+ IB_UVERBS_WC_RDMA_WRITE = 1, -+ IB_UVERBS_WC_RDMA_READ = 2, -+ IB_UVERBS_WC_COMP_SWAP = 3, -+ IB_UVERBS_WC_FETCH_ADD = 4, -+ IB_UVERBS_WC_BIND_MW = 5, -+ IB_UVERBS_WC_LOCAL_INV = 6, -+ IB_UVERBS_WC_TSO = 7, -+}; -+ -+struct ib_uverbs_wc { -+ __aligned_u64 wr_id; -+ __u32 status; -+ __u32 opcode; -+ __u32 vendor_err; -+ __u32 byte_len; -+ union { -+ __be32 imm_data; -+ __u32 invalidate_rkey; -+ } ex; -+ __u32 qp_num; -+ __u32 src_qp; -+ __u32 wc_flags; -+ __u16 pkey_index; -+ __u16 slid; -+ __u8 sl; -+ __u8 dlid_path_bits; -+ __u8 port_num; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_poll_cq_resp { -+ __u32 count; -+ __u32 reserved; -+ struct ib_uverbs_wc wc[0]; -+}; -+ -+struct ib_uverbs_req_notify_cq { -+ __u32 cq_handle; -+ __u32 solicited_only; -+}; -+ -+struct ib_uverbs_destroy_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_cq_resp { -+ __u32 comp_events_reported; -+ __u32 async_events_reported; -+}; -+ -+struct ib_uverbs_global_route { -+ __u8 dgid[16]; -+ __u32 flow_label; -+ __u8 sgid_index; -+ __u8 hop_limit; -+ __u8 traffic_class; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_ah_attr { -+ struct ib_uverbs_global_route grh; -+ __u16 dlid; -+ __u8 sl; -+ __u8 src_path_bits; -+ __u8 static_rate; -+ __u8 is_global; -+ __u8 port_num; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_qp_attr { -+ __u32 qp_attr_mask; -+ __u32 qp_state; -+ __u32 cur_qp_state; -+ __u32 path_mtu; -+ __u32 path_mig_state; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ -+ struct ib_uverbs_ah_attr ah_attr; -+ struct ib_uverbs_ah_attr alt_ah_attr; -+ -+ /* ib_qp_cap */ -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 en_sqd_async_notify; -+ __u8 sq_draining; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 reserved[5]; -+}; -+ -+struct ib_uverbs_create_qp { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 send_cq_handle; -+ __u32 recv_cq_handle; -+ __u32 srq_handle; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u8 sq_sig_all; -+ __u8 qp_type; -+ __u8 is_srq; -+ __u8 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+enum ib_uverbs_create_qp_mask { -+ IB_UVERBS_CREATE_QP_MASK_IND_TABLE = 1UL << 0, -+}; -+ -+enum { -+ IB_UVERBS_CREATE_QP_SUP_COMP_MASK = IB_UVERBS_CREATE_QP_MASK_IND_TABLE, -+}; -+ -+struct ib_uverbs_ex_create_qp { -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 send_cq_handle; -+ __u32 recv_cq_handle; -+ __u32 srq_handle; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u8 sq_sig_all; -+ __u8 qp_type; -+ __u8 is_srq; -+ __u8 reserved; -+ __u32 comp_mask; -+ __u32 create_flags; -+ __u32 rwq_ind_tbl_handle; -+ __u32 source_qpn; -+}; -+ -+struct ib_uverbs_open_qp { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 qpn; -+ __u8 qp_type; -+ __u8 reserved[7]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+/* also used for open response */ -+struct ib_uverbs_create_qp_resp { -+ __u32 qp_handle; -+ __u32 qpn; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u32 reserved; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_create_qp_resp { -+ struct ib_uverbs_create_qp_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+/* -+ * This struct needs to remain a multiple of 8 bytes to keep the -+ * alignment of the modify QP parameters. -+ */ -+struct ib_uverbs_qp_dest { -+ __u8 dgid[16]; -+ __u32 flow_label; -+ __u16 dlid; -+ __u16 reserved; -+ __u8 sgid_index; -+ __u8 hop_limit; -+ __u8 traffic_class; -+ __u8 sl; -+ __u8 src_path_bits; -+ __u8 static_rate; -+ __u8 is_global; -+ __u8 port_num; -+}; -+ -+struct ib_uverbs_query_qp { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 attr_mask; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_qp_resp { -+ struct ib_uverbs_qp_dest dest; -+ struct ib_uverbs_qp_dest alt_dest; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 qp_state; -+ __u8 cur_qp_state; -+ __u8 path_mtu; -+ __u8 path_mig_state; -+ __u8 sq_draining; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 sq_sig_all; -+ __u8 reserved[5]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_modify_qp { -+ struct ib_uverbs_qp_dest dest; -+ struct ib_uverbs_qp_dest alt_dest; -+ __u32 qp_handle; -+ __u32 attr_mask; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 qp_state; -+ __u8 cur_qp_state; -+ __u8 path_mtu; -+ __u8 path_mig_state; -+ __u8 en_sqd_async_notify; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 reserved[2]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_modify_qp { -+ struct ib_uverbs_modify_qp base; -+ __u32 rate_limit; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_modify_qp_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+struct ib_uverbs_destroy_qp { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_qp_resp { -+ __u32 events_reported; -+}; -+ -+/* -+ * The ib_uverbs_sge structure isn't used anywhere, since we assume -+ * the ib_sge structure is packed the same way on 32-bit and 64-bit -+ * architectures in both kernel and user space. It's just here to -+ * document the ABI. -+ */ -+struct ib_uverbs_sge { -+ __aligned_u64 addr; -+ __u32 length; -+ __u32 lkey; -+}; -+ -+enum ib_uverbs_wr_opcode { -+ IB_UVERBS_WR_RDMA_WRITE = 0, -+ IB_UVERBS_WR_RDMA_WRITE_WITH_IMM = 1, -+ IB_UVERBS_WR_SEND = 2, -+ IB_UVERBS_WR_SEND_WITH_IMM = 3, -+ IB_UVERBS_WR_RDMA_READ = 4, -+ IB_UVERBS_WR_ATOMIC_CMP_AND_SWP = 5, -+ IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD = 6, -+ IB_UVERBS_WR_LOCAL_INV = 7, -+ IB_UVERBS_WR_BIND_MW = 8, -+ IB_UVERBS_WR_SEND_WITH_INV = 9, -+ IB_UVERBS_WR_TSO = 10, -+ IB_UVERBS_WR_RDMA_READ_WITH_INV = 11, -+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12, -+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13, -+ /* Review enum ib_wr_opcode before modifying this */ -+}; -+ -+struct ib_uverbs_send_wr { -+ __aligned_u64 wr_id; -+ __u32 num_sge; -+ __u32 opcode; /* see enum ib_uverbs_wr_opcode */ -+ __u32 send_flags; -+ union { -+ __be32 imm_data; -+ __u32 invalidate_rkey; -+ } ex; -+ union { -+ struct { -+ __aligned_u64 remote_addr; -+ __u32 rkey; -+ __u32 reserved; -+ } rdma; -+ struct { -+ __aligned_u64 remote_addr; -+ __aligned_u64 compare_add; -+ __aligned_u64 swap; -+ __u32 rkey; -+ __u32 reserved; -+ } atomic; -+ struct { -+ __u32 ah; -+ __u32 remote_qpn; -+ __u32 remote_qkey; -+ __u32 reserved; -+ } ud; -+ } wr; -+}; -+ -+struct ib_uverbs_post_send { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_send_wr send_wr[0]; -+}; -+ -+struct ib_uverbs_post_send_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_recv_wr { -+ __aligned_u64 wr_id; -+ __u32 num_sge; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_post_recv { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_recv_wr recv_wr[0]; -+}; -+ -+struct ib_uverbs_post_recv_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_post_srq_recv { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_recv_wr recv[0]; -+}; -+ -+struct ib_uverbs_post_srq_recv_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_create_ah { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 reserved; -+ struct ib_uverbs_ah_attr attr; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_ah_resp { -+ __u32 ah_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_destroy_ah { -+ __u32 ah_handle; -+}; -+ -+struct ib_uverbs_attach_mcast { -+ __u8 gid[16]; -+ __u32 qp_handle; -+ __u16 mlid; -+ __u16 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_detach_mcast { -+ __u8 gid[16]; -+ __u32 qp_handle; -+ __u16 mlid; -+ __u16 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_flow_spec_hdr { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ /* followed by flow_spec */ -+ __aligned_u64 flow_spec_data[0]; -+}; -+ -+struct ib_uverbs_flow_eth_filter { -+ __u8 dst_mac[6]; -+ __u8 src_mac[6]; -+ __be16 ether_type; -+ __be16 vlan_tag; -+}; -+ -+struct ib_uverbs_flow_spec_eth { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_eth_filter val; -+ struct ib_uverbs_flow_eth_filter mask; -+}; -+ -+struct ib_uverbs_flow_ipv4_filter { -+ __be32 src_ip; -+ __be32 dst_ip; -+ __u8 proto; -+ __u8 tos; -+ __u8 ttl; -+ __u8 flags; -+}; -+ -+struct ib_uverbs_flow_spec_ipv4 { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_ipv4_filter val; -+ struct ib_uverbs_flow_ipv4_filter mask; -+}; -+ -+struct ib_uverbs_flow_tcp_udp_filter { -+ __be16 dst_port; -+ __be16 src_port; -+}; -+ -+struct ib_uverbs_flow_spec_tcp_udp { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_tcp_udp_filter val; -+ struct ib_uverbs_flow_tcp_udp_filter mask; -+}; -+ -+struct ib_uverbs_flow_ipv6_filter { -+ __u8 src_ip[16]; -+ __u8 dst_ip[16]; -+ __be32 flow_label; -+ __u8 next_hdr; -+ __u8 traffic_class; -+ __u8 hop_limit; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_flow_spec_ipv6 { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_ipv6_filter val; -+ struct ib_uverbs_flow_ipv6_filter mask; -+}; -+ -+struct ib_uverbs_flow_spec_action_tag { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 tag_id; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_spec_action_drop { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+}; -+ -+struct ib_uverbs_flow_spec_action_handle { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 handle; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_spec_action_count { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 handle; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_tunnel_filter { -+ __be32 tunnel_id; -+}; -+ -+struct ib_uverbs_flow_spec_tunnel { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_tunnel_filter val; -+ struct ib_uverbs_flow_tunnel_filter mask; -+}; -+ -+struct ib_uverbs_flow_spec_esp_filter { -+ __u32 spi; -+ __u32 seq; -+}; -+ -+struct ib_uverbs_flow_spec_esp { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_spec_esp_filter val; -+ struct ib_uverbs_flow_spec_esp_filter mask; -+}; -+ -+struct ib_uverbs_flow_gre_filter { -+ /* c_ks_res0_ver field is bits 0-15 in offset 0 of a standard GRE header: -+ * bit 0 - C - checksum bit. -+ * bit 1 - reserved. set to 0. -+ * bit 2 - key bit. -+ * bit 3 - sequence number bit. -+ * bits 4:12 - reserved. set to 0. -+ * bits 13:15 - GRE version. -+ */ -+ __be16 c_ks_res0_ver; -+ __be16 protocol; -+ __be32 key; -+}; -+ -+struct ib_uverbs_flow_spec_gre { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_gre_filter val; -+ struct ib_uverbs_flow_gre_filter mask; -+}; -+ -+struct ib_uverbs_flow_mpls_filter { -+ /* The field includes the entire MPLS label: -+ * bits 0:19 - label field. -+ * bits 20:22 - traffic class field. -+ * bits 23 - bottom of stack bit. -+ * bits 24:31 - ttl field. -+ */ -+ __be32 label; -+}; -+ -+struct ib_uverbs_flow_spec_mpls { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_mpls_filter val; -+ struct ib_uverbs_flow_mpls_filter mask; -+}; -+ -+struct ib_uverbs_flow_attr { -+ __u32 type; -+ __u16 size; -+ __u16 priority; -+ __u8 num_of_specs; -+ __u8 reserved[2]; -+ __u8 port; -+ __u32 flags; -+ /* Following are the optional layers according to user request -+ * struct ib_flow_spec_xxx -+ * struct ib_flow_spec_yyy -+ */ -+ struct ib_uverbs_flow_spec_hdr flow_specs[0]; -+}; -+ -+struct ib_uverbs_create_flow { -+ __u32 comp_mask; -+ __u32 qp_handle; -+ struct ib_uverbs_flow_attr flow_attr; -+}; -+ -+struct ib_uverbs_create_flow_resp { -+ __u32 comp_mask; -+ __u32 flow_handle; -+}; -+ -+struct ib_uverbs_destroy_flow { -+ __u32 comp_mask; -+ __u32 flow_handle; -+}; -+ -+struct ib_uverbs_create_srq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_xsrq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 srq_type; -+ __u32 pd_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __u32 max_num_tags; -+ __u32 xrcd_handle; -+ __u32 cq_handle; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_srq_resp { -+ __u32 srq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srqn; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_modify_srq { -+ __u32 srq_handle; -+ __u32 attr_mask; -+ __u32 max_wr; -+ __u32 srq_limit; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_srq { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_srq_resp { -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_srq { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_srq_resp { -+ __u32 events_reported; -+}; -+ -+struct ib_uverbs_ex_create_wq { -+ __u32 comp_mask; -+ __u32 wq_type; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 cq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 create_flags; /* Use enum ib_wq_flags */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_create_wq_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 wq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 wqn; -+}; -+ -+struct ib_uverbs_ex_destroy_wq { -+ __u32 comp_mask; -+ __u32 wq_handle; -+}; -+ -+struct ib_uverbs_ex_destroy_wq_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 events_reported; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_modify_wq { -+ __u32 attr_mask; -+ __u32 wq_handle; -+ __u32 wq_state; -+ __u32 curr_wq_state; -+ __u32 flags; /* Use enum ib_wq_flags */ -+ __u32 flags_mask; /* Use enum ib_wq_flags */ -+}; -+ -+/* Prevent memory allocation rather than max expected size */ -+#define IB_USER_VERBS_MAX_LOG_IND_TBL_SIZE 0x0d -+struct ib_uverbs_ex_create_rwq_ind_table { -+ __u32 comp_mask; -+ __u32 log_ind_tbl_size; -+ /* Following are the wq handles according to log_ind_tbl_size -+ * wq_handle1 -+ * wq_handle2 -+ */ -+ __u32 wq_handles[0]; -+}; -+ -+struct ib_uverbs_ex_create_rwq_ind_table_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 ind_tbl_handle; -+ __u32 ind_tbl_num; -+}; -+ -+struct ib_uverbs_ex_destroy_rwq_ind_table { -+ __u32 comp_mask; -+ __u32 ind_tbl_handle; -+}; -+ -+struct ib_uverbs_cq_moderation { -+ __u16 cq_count; -+ __u16 cq_period; -+}; -+ -+struct ib_uverbs_ex_modify_cq { -+ __u32 cq_handle; -+ __u32 attr_mask; -+ struct ib_uverbs_cq_moderation attr; -+ __u32 reserved; -+}; -+ -+#define IB_DEVICE_NAME_MAX 64 -+ -+#endif /* IB_USER_VERBS_H */ -diff --git a/src/rc-compat/v37/kern-abi.h b/src/rc-compat/v37/kern-abi.h -new file mode 100644 -index 000000000000..570b05fec462 ---- /dev/null -+++ b/src/rc-compat/v37/kern-abi.h -@@ -0,0 +1,322 @@ -+/* -+ * Copyright (c) 2005 Topspin Communications. All rights reserved. -+ * Copyright (c) 2005, 2006 Cisco Systems. 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. -+ */ -+ -+#ifndef KERN_ABI_H -+#define KERN_ABI_H -+ -+#include -+#include -+#include -+ -+#include -+#include "kernel-abi_ib_user_verbs.h" -+ -+/* -+ * The minimum and maximum kernel ABI that we can handle. -+ */ -+#define IB_USER_VERBS_MIN_ABI_VERSION 3 -+#define IB_USER_VERBS_MAX_ABI_VERSION 6 -+ -+struct ex_hdr { -+ struct ib_uverbs_cmd_hdr hdr; -+ struct ib_uverbs_ex_cmd_hdr ex_hdr; -+}; -+ -+/* -+ * These macros expand to type names that refer to the ABI structure type -+ * associated with the given enum string. -+ */ -+#define IBV_ABI_REQ(_enum) _ABI_REQ_STRUCT_##_enum -+#define IBV_KABI_REQ(_enum) _KABI_REQ_STRUCT_##_enum -+#define IBV_KABI_RESP(_enum) _KABI_RESP_STRUCT_##_enum -+ -+#define IBV_ABI_ALIGN(_enum) _ABI_ALIGN_##_enum -+ -+/* -+ * Historically the code had copied the data in the kernel headers, modified -+ * it and placed them in structs. To avoid recoding eveything we continue to -+ * preserve the same struct layout, with the kernel struct 'loose' inside the -+ * modified userspace struct. -+ * -+ * This is automated with the make_abi_structs.py script which produces the -+ * _STRUCT_xx macro that produces a tagless version of the kernel struct. The -+ * tagless struct produces a layout that matches the original code. -+ */ -+#define DECLARE_CMDX(_enum, _name, _kabi, _kabi_resp) \ -+ struct _name { \ -+ struct ib_uverbs_cmd_hdr hdr; \ -+ union { \ -+ _STRUCT_##_kabi; \ -+ struct _kabi core_payload; \ -+ }; \ -+ }; \ -+ typedef struct _name IBV_ABI_REQ(_enum); \ -+ typedef struct _kabi IBV_KABI_REQ(_enum); \ -+ typedef struct _kabi_resp IBV_KABI_RESP(_enum); \ -+ enum { IBV_ABI_ALIGN(_enum) = 4 }; \ -+ static_assert(sizeof(struct _kabi_resp) % 4 == 0, \ -+ "Bad resp alignment"); \ -+ static_assert(_enum != -1, "Bad enum"); \ -+ static_assert(sizeof(struct _name) == \ -+ sizeof(struct ib_uverbs_cmd_hdr) + \ -+ sizeof(struct _kabi), \ -+ "Bad size") -+ -+#define DECLARE_CMD(_enum, _name, _kabi) \ -+ DECLARE_CMDX(_enum, _name, _kabi, _kabi##_resp) -+ -+#define DECLARE_CMD_EXX(_enum, _name, _kabi, _kabi_resp) \ -+ struct _name { \ -+ struct ex_hdr hdr; \ -+ union { \ -+ _STRUCT_##_kabi; \ -+ struct _kabi core_payload; \ -+ }; \ -+ }; \ -+ typedef struct _name IBV_ABI_REQ(_enum); \ -+ typedef struct _kabi IBV_KABI_REQ(_enum); \ -+ typedef struct _kabi_resp IBV_KABI_RESP(_enum); \ -+ enum { IBV_ABI_ALIGN(_enum) = 8 }; \ -+ static_assert(_enum != -1, "Bad enum"); \ -+ static_assert(sizeof(struct _kabi) % 8 == 0, "Bad req alignment"); \ -+ static_assert(sizeof(struct _kabi_resp) % 8 == 0, \ -+ "Bad resp alignment"); \ -+ static_assert(sizeof(struct _name) == \ -+ sizeof(struct ex_hdr) + sizeof(struct _kabi), \ -+ "Bad size"); \ -+ static_assert(sizeof(struct _name) % 8 == 0, "Bad alignment") -+#define DECLARE_CMD_EX(_enum, _name, _kabi) \ -+ DECLARE_CMD_EXX(_enum, _name, _kabi, _kabi##_resp) -+ -+/* Drivers may use 'empty' for _kabi to signal no struct */ -+struct empty {}; -+#define _STRUCT_empty struct {} -+ -+/* -+ * Define the ABI struct for use by the driver. The internal cmd APIs require -+ * this layout. The driver specifies the enum # they wish to define for and -+ * the base name, and the macros figure out the rest correctly. -+ * -+ * The static asserts check that the layout produced by the wrapper struct has -+ * no implicit padding in strange places, specifically between the core -+ * structure and the driver structure and between the driver structure and the -+ * end of the struct. -+ * -+ * Implicit padding can arise in various cases where the structs are not sizes -+ * to a multiple of 8 bytes. -+ */ -+#define DECLARE_DRV_CMD(_name, _enum, _kabi_req, _kabi_resp) \ -+ struct _name { \ -+ IBV_ABI_REQ(_enum) ibv_cmd; \ -+ union { \ -+ _STRUCT_##_kabi_req; \ -+ struct _kabi_req drv_payload; \ -+ }; \ -+ }; \ -+ struct _name##_resp { \ -+ IBV_KABI_RESP(_enum) ibv_resp; \ -+ union { \ -+ _STRUCT_##_kabi_resp; \ -+ struct _kabi_resp drv_payload; \ -+ }; \ -+ }; \ -+ static_assert(sizeof(IBV_KABI_REQ(_enum)) % \ -+ __alignof__(struct _kabi_req) == \ -+ 0, \ -+ "Bad kabi req struct length"); \ -+ static_assert(sizeof(struct _name) == \ -+ sizeof(IBV_ABI_REQ(_enum)) + \ -+ sizeof(struct _kabi_req), \ -+ "Bad req size"); \ -+ static_assert(sizeof(struct _name) % IBV_ABI_ALIGN(_enum) == 0, \ -+ "Bad kabi req alignment"); \ -+ static_assert(sizeof(IBV_KABI_RESP(_enum)) % \ -+ __alignof__(struct _kabi_resp) == \ -+ 0, \ -+ "Bad kabi resp struct length"); \ -+ static_assert(sizeof(struct _name##_resp) == \ -+ sizeof(IBV_KABI_RESP(_enum)) + \ -+ sizeof(struct _kabi_resp), \ -+ "Bad resp size"); \ -+ static_assert(sizeof(struct _name##_resp) % IBV_ABI_ALIGN(_enum) == 0, \ -+ "Bad kabi resp alignment"); -+ -+DECLARE_CMD(IB_USER_VERBS_CMD_ALLOC_MW, ibv_alloc_mw, ib_uverbs_alloc_mw); -+DECLARE_CMD(IB_USER_VERBS_CMD_ALLOC_PD, ibv_alloc_pd, ib_uverbs_alloc_pd); -+DECLARE_CMDX(IB_USER_VERBS_CMD_ATTACH_MCAST, ibv_attach_mcast, ib_uverbs_attach_mcast, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_CLOSE_XRCD, ibv_close_xrcd, ib_uverbs_close_xrcd, empty); -+DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_AH, ibv_create_ah, ib_uverbs_create_ah); -+DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL, ibv_create_comp_channel, ib_uverbs_create_comp_channel); -+DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_CQ, ibv_create_cq, ib_uverbs_create_cq); -+DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_QP, ibv_create_qp, ib_uverbs_create_qp); -+DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_SRQ, ibv_create_srq, ib_uverbs_create_srq); -+DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_XSRQ, ibv_create_xsrq, ib_uverbs_create_xsrq, ib_uverbs_create_srq_resp); -+DECLARE_CMDX(IB_USER_VERBS_CMD_DEALLOC_MW, ibv_dealloc_mw, ib_uverbs_dealloc_mw, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_DEALLOC_PD, ibv_dealloc_pd, ib_uverbs_dealloc_pd, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_DEREG_MR, ibv_dereg_mr, ib_uverbs_dereg_mr, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_DESTROY_AH, ibv_destroy_ah, ib_uverbs_destroy_ah, empty); -+DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_CQ, ibv_destroy_cq, ib_uverbs_destroy_cq); -+DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_QP, ibv_destroy_qp, ib_uverbs_destroy_qp); -+DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_SRQ, ibv_destroy_srq, ib_uverbs_destroy_srq); -+DECLARE_CMDX(IB_USER_VERBS_CMD_DETACH_MCAST, ibv_detach_mcast, ib_uverbs_detach_mcast, empty); -+DECLARE_CMD(IB_USER_VERBS_CMD_GET_CONTEXT, ibv_get_context, ib_uverbs_get_context); -+DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_QP, ibv_modify_qp, ib_uverbs_modify_qp, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_SRQ, ibv_modify_srq, ib_uverbs_modify_srq, empty); -+DECLARE_CMDX(IB_USER_VERBS_CMD_OPEN_QP, ibv_open_qp, ib_uverbs_open_qp, ib_uverbs_create_qp_resp); -+DECLARE_CMD(IB_USER_VERBS_CMD_OPEN_XRCD, ibv_open_xrcd, ib_uverbs_open_xrcd); -+DECLARE_CMD(IB_USER_VERBS_CMD_POLL_CQ, ibv_poll_cq, ib_uverbs_poll_cq); -+DECLARE_CMD(IB_USER_VERBS_CMD_POST_RECV, ibv_post_recv, ib_uverbs_post_recv); -+DECLARE_CMD(IB_USER_VERBS_CMD_POST_SEND, ibv_post_send, ib_uverbs_post_send); -+DECLARE_CMD(IB_USER_VERBS_CMD_POST_SRQ_RECV, ibv_post_srq_recv, ib_uverbs_post_srq_recv); -+DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_DEVICE, ibv_query_device, ib_uverbs_query_device); -+DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_PORT, ibv_query_port, ib_uverbs_query_port); -+DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_QP, ibv_query_qp, ib_uverbs_query_qp); -+DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_SRQ, ibv_query_srq, ib_uverbs_query_srq); -+DECLARE_CMD(IB_USER_VERBS_CMD_REG_MR, ibv_reg_mr, ib_uverbs_reg_mr); -+DECLARE_CMDX(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ, ibv_req_notify_cq, ib_uverbs_req_notify_cq, empty); -+DECLARE_CMD(IB_USER_VERBS_CMD_REREG_MR, ibv_rereg_mr, ib_uverbs_rereg_mr); -+DECLARE_CMD(IB_USER_VERBS_CMD_RESIZE_CQ, ibv_resize_cq, ib_uverbs_resize_cq); -+ -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_CQ, ibv_create_cq_ex, ib_uverbs_ex_create_cq); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_FLOW, ibv_create_flow, ib_uverbs_create_flow); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_QP, ibv_create_qp_ex, ib_uverbs_ex_create_qp); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL, ibv_create_rwq_ind_table, ib_uverbs_ex_create_rwq_ind_table); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_WQ, ibv_create_wq, ib_uverbs_ex_create_wq); -+DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_DESTROY_FLOW, ibv_destroy_flow, ib_uverbs_destroy_flow, empty); -+DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL, ibv_destroy_rwq_ind_table, ib_uverbs_ex_destroy_rwq_ind_table, empty); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_DESTROY_WQ, ibv_destroy_wq, ib_uverbs_ex_destroy_wq); -+DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_MODIFY_CQ, ibv_modify_cq, ib_uverbs_ex_modify_cq, empty); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_MODIFY_QP, ibv_modify_qp_ex, ib_uverbs_ex_modify_qp); -+DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_MODIFY_WQ, ibv_modify_wq, ib_uverbs_ex_modify_wq, empty); -+DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_QUERY_DEVICE, ibv_query_device_ex, ib_uverbs_ex_query_device); -+ -+/* -+ * Both ib_uverbs_create_qp and ib_uverbs_ex_create_qp start with the same -+ * structure, this function converts the ex version into the normal version -+ */ -+static inline struct ib_uverbs_create_qp * -+ibv_create_qp_ex_to_reg(struct ibv_create_qp_ex *cmd_ex) -+{ -+ /* -+ * user_handle is the start in both places, note that the ex -+ * does not have response located in the same place, so response -+ * cannot be touched. -+ */ -+ return container_of(&cmd_ex->user_handle, struct ib_uverbs_create_qp, -+ user_handle); -+} -+ -+/* -+ * This file contains copied data from the kernel's include/uapi/rdma/ib_user_verbs.h, -+ * now included above. -+ * -+ * Whenever possible use the definition from the kernel header and avoid -+ * copying from that header into this file. -+ */ -+ -+struct ibv_kern_ipv4_filter { -+ __u32 src_ip; -+ __u32 dst_ip; -+}; -+ -+struct ibv_kern_spec_ipv4 { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ struct ibv_kern_ipv4_filter val; -+ struct ibv_kern_ipv4_filter mask; -+}; -+ -+struct ibv_kern_spec { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct ib_uverbs_flow_spec_eth eth; -+ struct ibv_kern_spec_ipv4 ipv4; -+ struct ib_uverbs_flow_spec_ipv4 ipv4_ext; -+ struct ib_uverbs_flow_spec_esp esp; -+ struct ib_uverbs_flow_spec_tcp_udp tcp_udp; -+ struct ib_uverbs_flow_spec_ipv6 ipv6; -+ struct ib_uverbs_flow_spec_gre gre; -+ struct ib_uverbs_flow_spec_tunnel tunnel; -+ struct ib_uverbs_flow_spec_mpls mpls; -+ struct ib_uverbs_flow_spec_action_tag flow_tag; -+ struct ib_uverbs_flow_spec_action_drop drop; -+ struct ib_uverbs_flow_spec_action_handle handle; -+ struct ib_uverbs_flow_spec_action_count flow_count; -+ }; -+}; -+ -+struct ib_uverbs_modify_srq_v3 { -+ __u32 srq_handle; -+ __u32 attr_mask; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __u32 reserved; -+}; -+#define _STRUCT_ib_uverbs_modify_srq_v3 -+enum { IB_USER_VERBS_CMD_MODIFY_SRQ_V3 = IB_USER_VERBS_CMD_MODIFY_SRQ }; -+DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_SRQ_V3, ibv_modify_srq_v3, ib_uverbs_modify_srq_v3, empty); -+ -+struct ibv_create_qp_resp_v3 { -+ __u32 qp_handle; -+ __u32 qpn; -+}; -+ -+struct ibv_create_qp_resp_v4 { -+ __u32 qp_handle; -+ __u32 qpn; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+}; -+ -+struct ibv_create_srq_resp_v5 { -+ __u32 srq_handle; -+}; -+ -+#define _STRUCT_ib_uverbs_create_srq_v5 -+enum { IB_USER_VERBS_CMD_CREATE_SRQ_V5 = IB_USER_VERBS_CMD_CREATE_SRQ }; -+DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_SRQ_V5, ibv_create_srq_v5, ib_uverbs_create_srq, ibv_create_srq_resp_v5); -+ -+#define _STRUCT_ib_uverbs_create_qp_v4 -+enum { IB_USER_VERBS_CMD_CREATE_QP_V4 = IB_USER_VERBS_CMD_CREATE_QP }; -+DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_QP_V4, ibv_create_qp_v4, ib_uverbs_create_qp, ibv_create_qp_resp_v4); -+ -+#define _STRUCT_ib_uverbs_create_qp_v3 -+enum { IB_USER_VERBS_CMD_CREATE_QP_V3 = IB_USER_VERBS_CMD_CREATE_QP }; -+DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_QP_V3, ibv_create_qp_v3, ib_uverbs_create_qp, ibv_create_qp_resp_v3); -+#endif /* KERN_ABI_H */ -diff --git a/src/rc-compat/v37/kernel-abi_ib_user_verbs.h b/src/rc-compat/v37/kernel-abi_ib_user_verbs.h -new file mode 100644 -index 000000000000..fbe4ae635b84 ---- /dev/null -+++ b/src/rc-compat/v37/kernel-abi_ib_user_verbs.h -@@ -0,0 +1,1114 @@ -+#define _STRUCT_ib_uverbs_async_event_desc struct { \ -+__aligned_u64 element; \ -+__u32 event_type; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_comp_event_desc struct { \ -+__aligned_u64 cq_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_cq_moderation_caps struct { \ -+__u16 max_cq_moderation_count; \ -+__u16 max_cq_moderation_period; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_cmd_hdr struct { \ -+__u32 command; \ -+__u16 in_words; \ -+__u16 out_words; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_cmd_hdr struct { \ -+__aligned_u64 response; \ -+__u16 provider_in_words; \ -+__u16 provider_out_words; \ -+__u32 cmd_hdr_reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_get_context struct { \ -+__aligned_u64 response; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_get_context_resp struct { \ -+__u32 async_fd; \ -+__u32 num_comp_vectors; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_device struct { \ -+__aligned_u64 response; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_device_resp struct { \ -+__aligned_u64 fw_ver; \ -+__be64 node_guid; \ -+__be64 sys_image_guid; \ -+__aligned_u64 max_mr_size; \ -+__aligned_u64 page_size_cap; \ -+__u32 vendor_id; \ -+__u32 vendor_part_id; \ -+__u32 hw_ver; \ -+__u32 max_qp; \ -+__u32 max_qp_wr; \ -+__u32 device_cap_flags; \ -+__u32 max_sge; \ -+__u32 max_sge_rd; \ -+__u32 max_cq; \ -+__u32 max_cqe; \ -+__u32 max_mr; \ -+__u32 max_pd; \ -+__u32 max_qp_rd_atom; \ -+__u32 max_ee_rd_atom; \ -+__u32 max_res_rd_atom; \ -+__u32 max_qp_init_rd_atom; \ -+__u32 max_ee_init_rd_atom; \ -+__u32 atomic_cap; \ -+__u32 max_ee; \ -+__u32 max_rdd; \ -+__u32 max_mw; \ -+__u32 max_raw_ipv6_qp; \ -+__u32 max_raw_ethy_qp; \ -+__u32 max_mcast_grp; \ -+__u32 max_mcast_qp_attach; \ -+__u32 max_total_mcast_qp_attach; \ -+__u32 max_ah; \ -+__u32 max_fmr; \ -+__u32 max_map_per_fmr; \ -+__u32 max_srq; \ -+__u32 max_srq_wr; \ -+__u32 max_srq_sge; \ -+__u16 max_pkeys; \ -+__u8 local_ca_ack_delay; \ -+__u8 phys_port_cnt; \ -+__u8 reserved[4]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_query_device struct { \ -+__u32 comp_mask; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_odp_caps struct { \ -+__aligned_u64 general_caps; \ -+struct { \ -+__u32 rc_odp_caps; \ -+__u32 uc_odp_caps; \ -+__u32 ud_odp_caps; \ -+} per_transport_caps; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_rss_caps struct { \ -+/* Corresponding bit will be set if qp type from \ -+* 'enum ib_qp_type' is supported, e.g. \ -+* supported_qpts |= 1 << IB_QPT_UD \ -+*/ \ -+__u32 supported_qpts; \ -+__u32 max_rwq_indirection_tables; \ -+__u32 max_rwq_indirection_table_size; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_tm_caps struct { \ -+ \ -+__u32 max_rndv_hdr_size; \ -+ \ -+__u32 max_num_tags; \ -+ \ -+__u32 flags; \ -+ \ -+__u32 max_ops; \ -+ \ -+__u32 max_sge; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_query_device_resp struct { \ -+struct ib_uverbs_query_device_resp base; \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+struct ib_uverbs_odp_caps odp_caps; \ -+__aligned_u64 timestamp_mask; \ -+__aligned_u64 hca_core_clock; \ -+__aligned_u64 device_cap_flags_ex; \ -+struct ib_uverbs_rss_caps rss_caps; \ -+__u32 max_wq_type_rq; \ -+__u32 raw_packet_caps; \ -+struct ib_uverbs_tm_caps tm_caps; \ -+struct ib_uverbs_cq_moderation_caps cq_moderation_caps; \ -+__aligned_u64 max_dm_size; \ -+__u32 xrc_odp_caps; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_port struct { \ -+__aligned_u64 response; \ -+__u8 port_num; \ -+__u8 reserved[7]; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_port_resp struct { \ -+__u32 port_cap_flags; \ -+__u32 max_msg_sz; \ -+__u32 bad_pkey_cntr; \ -+__u32 qkey_viol_cntr; \ -+__u32 gid_tbl_len; \ -+__u16 pkey_tbl_len; \ -+__u16 lid; \ -+__u16 sm_lid; \ -+__u8 state; \ -+__u8 max_mtu; \ -+__u8 active_mtu; \ -+__u8 lmc; \ -+__u8 max_vl_num; \ -+__u8 sm_sl; \ -+__u8 subnet_timeout; \ -+__u8 init_type_reply; \ -+__u8 active_width; \ -+__u8 active_speed; \ -+__u8 phys_state; \ -+__u8 link_layer; \ -+__u8 flags; \ -+__u8 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_alloc_pd struct { \ -+__aligned_u64 response; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_alloc_pd_resp struct { \ -+__u32 pd_handle; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_dealloc_pd struct { \ -+__u32 pd_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_open_xrcd struct { \ -+__aligned_u64 response; \ -+__u32 fd; \ -+__u32 oflags; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_open_xrcd_resp struct { \ -+__u32 xrcd_handle; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_close_xrcd struct { \ -+__u32 xrcd_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_reg_mr struct { \ -+__aligned_u64 response; \ -+__aligned_u64 start; \ -+__aligned_u64 length; \ -+__aligned_u64 hca_va; \ -+__u32 pd_handle; \ -+__u32 access_flags; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_reg_mr_resp struct { \ -+__u32 mr_handle; \ -+__u32 lkey; \ -+__u32 rkey; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_rereg_mr struct { \ -+__aligned_u64 response; \ -+__u32 mr_handle; \ -+__u32 flags; \ -+__aligned_u64 start; \ -+__aligned_u64 length; \ -+__aligned_u64 hca_va; \ -+__u32 pd_handle; \ -+__u32 access_flags; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_rereg_mr_resp struct { \ -+__u32 lkey; \ -+__u32 rkey; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_dereg_mr struct { \ -+__u32 mr_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_alloc_mw struct { \ -+__aligned_u64 response; \ -+__u32 pd_handle; \ -+__u8 mw_type; \ -+__u8 reserved[3]; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_alloc_mw_resp struct { \ -+__u32 mw_handle; \ -+__u32 rkey; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_dealloc_mw struct { \ -+__u32 mw_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_comp_channel struct { \ -+__aligned_u64 response; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_comp_channel_resp struct { \ -+__u32 fd; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_cq struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 cqe; \ -+__u32 comp_vector; \ -+__s32 comp_channel; \ -+__u32 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_cq struct { \ -+__aligned_u64 user_handle; \ -+__u32 cqe; \ -+__u32 comp_vector; \ -+__s32 comp_channel; \ -+__u32 comp_mask; \ -+__u32 flags; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_cq_resp struct { \ -+__u32 cq_handle; \ -+__u32 cqe; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_cq_resp struct { \ -+struct ib_uverbs_create_cq_resp base; \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+} -+ -+#define _STRUCT_ib_uverbs_resize_cq struct { \ -+__aligned_u64 response; \ -+__u32 cq_handle; \ -+__u32 cqe; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_resize_cq_resp struct { \ -+__u32 cqe; \ -+__u32 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_poll_cq struct { \ -+__aligned_u64 response; \ -+__u32 cq_handle; \ -+__u32 ne; \ -+} -+ -+#define _STRUCT_ib_uverbs_wc struct { \ -+__aligned_u64 wr_id; \ -+__u32 status; \ -+__u32 opcode; \ -+__u32 vendor_err; \ -+__u32 byte_len; \ -+union { \ -+__be32 imm_data; \ -+__u32 invalidate_rkey; \ -+} ex; \ -+__u32 qp_num; \ -+__u32 src_qp; \ -+__u32 wc_flags; \ -+__u16 pkey_index; \ -+__u16 slid; \ -+__u8 sl; \ -+__u8 dlid_path_bits; \ -+__u8 port_num; \ -+__u8 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_poll_cq_resp struct { \ -+__u32 count; \ -+__u32 reserved; \ -+struct ib_uverbs_wc wc[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_req_notify_cq struct { \ -+__u32 cq_handle; \ -+__u32 solicited_only; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_cq struct { \ -+__aligned_u64 response; \ -+__u32 cq_handle; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_cq_resp struct { \ -+__u32 comp_events_reported; \ -+__u32 async_events_reported; \ -+} -+ -+#define _STRUCT_ib_uverbs_global_route struct { \ -+__u8 dgid[16]; \ -+__u32 flow_label; \ -+__u8 sgid_index; \ -+__u8 hop_limit; \ -+__u8 traffic_class; \ -+__u8 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_ah_attr struct { \ -+struct ib_uverbs_global_route grh; \ -+__u16 dlid; \ -+__u8 sl; \ -+__u8 src_path_bits; \ -+__u8 static_rate; \ -+__u8 is_global; \ -+__u8 port_num; \ -+__u8 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_qp_attr struct { \ -+__u32 qp_attr_mask; \ -+__u32 qp_state; \ -+__u32 cur_qp_state; \ -+__u32 path_mtu; \ -+__u32 path_mig_state; \ -+__u32 qkey; \ -+__u32 rq_psn; \ -+__u32 sq_psn; \ -+__u32 dest_qp_num; \ -+__u32 qp_access_flags; \ -+ \ -+struct ib_uverbs_ah_attr ah_attr; \ -+struct ib_uverbs_ah_attr alt_ah_attr; \ -+ \ -+ \ -+__u32 max_send_wr; \ -+__u32 max_recv_wr; \ -+__u32 max_send_sge; \ -+__u32 max_recv_sge; \ -+__u32 max_inline_data; \ -+ \ -+__u16 pkey_index; \ -+__u16 alt_pkey_index; \ -+__u8 en_sqd_async_notify; \ -+__u8 sq_draining; \ -+__u8 max_rd_atomic; \ -+__u8 max_dest_rd_atomic; \ -+__u8 min_rnr_timer; \ -+__u8 port_num; \ -+__u8 timeout; \ -+__u8 retry_cnt; \ -+__u8 rnr_retry; \ -+__u8 alt_port_num; \ -+__u8 alt_timeout; \ -+__u8 reserved[5]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_qp struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 send_cq_handle; \ -+__u32 recv_cq_handle; \ -+__u32 srq_handle; \ -+__u32 max_send_wr; \ -+__u32 max_recv_wr; \ -+__u32 max_send_sge; \ -+__u32 max_recv_sge; \ -+__u32 max_inline_data; \ -+__u8 sq_sig_all; \ -+__u8 qp_type; \ -+__u8 is_srq; \ -+__u8 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_qp struct { \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 send_cq_handle; \ -+__u32 recv_cq_handle; \ -+__u32 srq_handle; \ -+__u32 max_send_wr; \ -+__u32 max_recv_wr; \ -+__u32 max_send_sge; \ -+__u32 max_recv_sge; \ -+__u32 max_inline_data; \ -+__u8 sq_sig_all; \ -+__u8 qp_type; \ -+__u8 is_srq; \ -+__u8 reserved; \ -+__u32 comp_mask; \ -+__u32 create_flags; \ -+__u32 rwq_ind_tbl_handle; \ -+__u32 source_qpn; \ -+} -+ -+#define _STRUCT_ib_uverbs_open_qp struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 qpn; \ -+__u8 qp_type; \ -+__u8 reserved[7]; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_qp_resp struct { \ -+__u32 qp_handle; \ -+__u32 qpn; \ -+__u32 max_send_wr; \ -+__u32 max_recv_wr; \ -+__u32 max_send_sge; \ -+__u32 max_recv_sge; \ -+__u32 max_inline_data; \ -+__u32 reserved; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_qp_resp struct { \ -+struct ib_uverbs_create_qp_resp base; \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+} -+ -+#define _STRUCT_ib_uverbs_qp_dest struct { \ -+__u8 dgid[16]; \ -+__u32 flow_label; \ -+__u16 dlid; \ -+__u16 reserved; \ -+__u8 sgid_index; \ -+__u8 hop_limit; \ -+__u8 traffic_class; \ -+__u8 sl; \ -+__u8 src_path_bits; \ -+__u8 static_rate; \ -+__u8 is_global; \ -+__u8 port_num; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_qp struct { \ -+__aligned_u64 response; \ -+__u32 qp_handle; \ -+__u32 attr_mask; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_qp_resp struct { \ -+struct ib_uverbs_qp_dest dest; \ -+struct ib_uverbs_qp_dest alt_dest; \ -+__u32 max_send_wr; \ -+__u32 max_recv_wr; \ -+__u32 max_send_sge; \ -+__u32 max_recv_sge; \ -+__u32 max_inline_data; \ -+__u32 qkey; \ -+__u32 rq_psn; \ -+__u32 sq_psn; \ -+__u32 dest_qp_num; \ -+__u32 qp_access_flags; \ -+__u16 pkey_index; \ -+__u16 alt_pkey_index; \ -+__u8 qp_state; \ -+__u8 cur_qp_state; \ -+__u8 path_mtu; \ -+__u8 path_mig_state; \ -+__u8 sq_draining; \ -+__u8 max_rd_atomic; \ -+__u8 max_dest_rd_atomic; \ -+__u8 min_rnr_timer; \ -+__u8 port_num; \ -+__u8 timeout; \ -+__u8 retry_cnt; \ -+__u8 rnr_retry; \ -+__u8 alt_port_num; \ -+__u8 alt_timeout; \ -+__u8 sq_sig_all; \ -+__u8 reserved[5]; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_modify_qp struct { \ -+struct ib_uverbs_qp_dest dest; \ -+struct ib_uverbs_qp_dest alt_dest; \ -+__u32 qp_handle; \ -+__u32 attr_mask; \ -+__u32 qkey; \ -+__u32 rq_psn; \ -+__u32 sq_psn; \ -+__u32 dest_qp_num; \ -+__u32 qp_access_flags; \ -+__u16 pkey_index; \ -+__u16 alt_pkey_index; \ -+__u8 qp_state; \ -+__u8 cur_qp_state; \ -+__u8 path_mtu; \ -+__u8 path_mig_state; \ -+__u8 en_sqd_async_notify; \ -+__u8 max_rd_atomic; \ -+__u8 max_dest_rd_atomic; \ -+__u8 min_rnr_timer; \ -+__u8 port_num; \ -+__u8 timeout; \ -+__u8 retry_cnt; \ -+__u8 rnr_retry; \ -+__u8 alt_port_num; \ -+__u8 alt_timeout; \ -+__u8 reserved[2]; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_modify_qp struct { \ -+struct ib_uverbs_modify_qp base; \ -+__u32 rate_limit; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_modify_qp_resp struct { \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_qp struct { \ -+__aligned_u64 response; \ -+__u32 qp_handle; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_qp_resp struct { \ -+__u32 events_reported; \ -+} -+ -+#define _STRUCT_ib_uverbs_sge struct { \ -+__aligned_u64 addr; \ -+__u32 length; \ -+__u32 lkey; \ -+} -+ -+#define _STRUCT_ib_uverbs_send_wr struct { \ -+__aligned_u64 wr_id; \ -+__u32 num_sge; \ -+__u32 opcode; \ -+__u32 send_flags; \ -+union { \ -+__be32 imm_data; \ -+__u32 invalidate_rkey; \ -+} ex; \ -+union { \ -+struct { \ -+__aligned_u64 remote_addr; \ -+__u32 rkey; \ -+__u32 reserved; \ -+} rdma; \ -+struct { \ -+__aligned_u64 remote_addr; \ -+__aligned_u64 compare_add; \ -+__aligned_u64 swap; \ -+__u32 rkey; \ -+__u32 reserved; \ -+} atomic; \ -+struct { \ -+__u32 ah; \ -+__u32 remote_qpn; \ -+__u32 remote_qkey; \ -+__u32 reserved; \ -+} ud; \ -+} wr; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_send struct { \ -+__aligned_u64 response; \ -+__u32 qp_handle; \ -+__u32 wr_count; \ -+__u32 sge_count; \ -+__u32 wqe_size; \ -+struct ib_uverbs_send_wr send_wr[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_send_resp struct { \ -+__u32 bad_wr; \ -+} -+ -+#define _STRUCT_ib_uverbs_recv_wr struct { \ -+__aligned_u64 wr_id; \ -+__u32 num_sge; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_recv struct { \ -+__aligned_u64 response; \ -+__u32 qp_handle; \ -+__u32 wr_count; \ -+__u32 sge_count; \ -+__u32 wqe_size; \ -+struct ib_uverbs_recv_wr recv_wr[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_recv_resp struct { \ -+__u32 bad_wr; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_srq_recv struct { \ -+__aligned_u64 response; \ -+__u32 srq_handle; \ -+__u32 wr_count; \ -+__u32 sge_count; \ -+__u32 wqe_size; \ -+struct ib_uverbs_recv_wr recv[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_post_srq_recv_resp struct { \ -+__u32 bad_wr; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_ah struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 reserved; \ -+struct ib_uverbs_ah_attr attr; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_ah_resp struct { \ -+__u32 ah_handle; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_ah struct { \ -+__u32 ah_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_attach_mcast struct { \ -+__u8 gid[16]; \ -+__u32 qp_handle; \ -+__u16 mlid; \ -+__u16 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_detach_mcast struct { \ -+__u8 gid[16]; \ -+__u32 qp_handle; \ -+__u16 mlid; \ -+__u16 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_hdr struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+ \ -+__aligned_u64 flow_spec_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_eth_filter struct { \ -+__u8 dst_mac[6]; \ -+__u8 src_mac[6]; \ -+__be16 ether_type; \ -+__be16 vlan_tag; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_eth struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_eth_filter val; \ -+struct ib_uverbs_flow_eth_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_ipv4_filter struct { \ -+__be32 src_ip; \ -+__be32 dst_ip; \ -+__u8 proto; \ -+__u8 tos; \ -+__u8 ttl; \ -+__u8 flags; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_ipv4 struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_ipv4_filter val; \ -+struct ib_uverbs_flow_ipv4_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_tcp_udp_filter struct { \ -+__be16 dst_port; \ -+__be16 src_port; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_tcp_udp struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_tcp_udp_filter val; \ -+struct ib_uverbs_flow_tcp_udp_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_ipv6_filter struct { \ -+__u8 src_ip[16]; \ -+__u8 dst_ip[16]; \ -+__be32 flow_label; \ -+__u8 next_hdr; \ -+__u8 traffic_class; \ -+__u8 hop_limit; \ -+__u8 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_ipv6 struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_ipv6_filter val; \ -+struct ib_uverbs_flow_ipv6_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_action_tag struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+__u32 tag_id; \ -+__u32 reserved1; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_action_drop struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_action_handle struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+__u32 handle; \ -+__u32 reserved1; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_action_count struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+__u32 handle; \ -+__u32 reserved1; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_tunnel_filter struct { \ -+__be32 tunnel_id; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_tunnel struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_tunnel_filter val; \ -+struct ib_uverbs_flow_tunnel_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_esp_filter struct { \ -+__u32 spi; \ -+__u32 seq; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_esp struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_spec_esp_filter val; \ -+struct ib_uverbs_flow_spec_esp_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_gre_filter struct { \ -+/* c_ks_res0_ver field is bits 0-15 in offset 0 of a standard GRE header: \ -+* bit 0 - C - checksum bit. \ -+* bit 1 - reserved. set to 0. \ -+* bit 2 - key bit. \ -+* bit 3 - sequence number bit. \ -+* bits 4:12 - reserved. set to 0. \ -+* bits 13:15 - GRE version. \ -+*/ \ -+__be16 c_ks_res0_ver; \ -+__be16 protocol; \ -+__be32 key; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_gre struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_gre_filter val; \ -+struct ib_uverbs_flow_gre_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_mpls_filter struct { \ -+/* The field includes the entire MPLS label: \ -+* bits 0:19 - label field. \ -+* bits 20:22 - traffic class field. \ -+* bits 23 - bottom of stack bit. \ -+* bits 24:31 - ttl field. \ -+*/ \ -+__be32 label; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_spec_mpls struct { \ -+union { \ -+struct ib_uverbs_flow_spec_hdr hdr; \ -+struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 reserved; \ -+}; \ -+}; \ -+struct ib_uverbs_flow_mpls_filter val; \ -+struct ib_uverbs_flow_mpls_filter mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_flow_attr struct { \ -+__u32 type; \ -+__u16 size; \ -+__u16 priority; \ -+__u8 num_of_specs; \ -+__u8 reserved[2]; \ -+__u8 port; \ -+__u32 flags; \ -+/* Following are the optional layers according to user request \ -+* struct ib_flow_spec_xxx \ -+* struct ib_flow_spec_yyy \ -+*/ \ -+struct ib_uverbs_flow_spec_hdr flow_specs[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_flow struct { \ -+__u32 comp_mask; \ -+__u32 qp_handle; \ -+struct ib_uverbs_flow_attr flow_attr; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_flow_resp struct { \ -+__u32 comp_mask; \ -+__u32 flow_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_flow struct { \ -+__u32 comp_mask; \ -+__u32 flow_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_srq struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 srq_limit; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_xsrq struct { \ -+__aligned_u64 response; \ -+__aligned_u64 user_handle; \ -+__u32 srq_type; \ -+__u32 pd_handle; \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 srq_limit; \ -+__u32 max_num_tags; \ -+__u32 xrcd_handle; \ -+__u32 cq_handle; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_create_srq_resp struct { \ -+__u32 srq_handle; \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 srqn; \ -+__u32 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_modify_srq struct { \ -+__u32 srq_handle; \ -+__u32 attr_mask; \ -+__u32 max_wr; \ -+__u32 srq_limit; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_srq struct { \ -+__aligned_u64 response; \ -+__u32 srq_handle; \ -+__u32 reserved; \ -+__aligned_u64 driver_data[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_query_srq_resp struct { \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 srq_limit; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_srq struct { \ -+__aligned_u64 response; \ -+__u32 srq_handle; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_destroy_srq_resp struct { \ -+__u32 events_reported; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_wq struct { \ -+__u32 comp_mask; \ -+__u32 wq_type; \ -+__aligned_u64 user_handle; \ -+__u32 pd_handle; \ -+__u32 cq_handle; \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 create_flags; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_wq_resp struct { \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+__u32 wq_handle; \ -+__u32 max_wr; \ -+__u32 max_sge; \ -+__u32 wqn; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_destroy_wq struct { \ -+__u32 comp_mask; \ -+__u32 wq_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_destroy_wq_resp struct { \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+__u32 events_reported; \ -+__u32 reserved; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_modify_wq struct { \ -+__u32 attr_mask; \ -+__u32 wq_handle; \ -+__u32 wq_state; \ -+__u32 curr_wq_state; \ -+__u32 flags; \ -+__u32 flags_mask; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_rwq_ind_table struct { \ -+__u32 comp_mask; \ -+__u32 log_ind_tbl_size; \ -+/* Following are the wq handles according to log_ind_tbl_size \ -+* wq_handle1 \ -+* wq_handle2 \ -+*/ \ -+__u32 wq_handles[0]; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_create_rwq_ind_table_resp struct { \ -+__u32 comp_mask; \ -+__u32 response_length; \ -+__u32 ind_tbl_handle; \ -+__u32 ind_tbl_num; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_destroy_rwq_ind_table struct { \ -+__u32 comp_mask; \ -+__u32 ind_tbl_handle; \ -+} -+ -+#define _STRUCT_ib_uverbs_cq_moderation struct { \ -+__u16 cq_count; \ -+__u16 cq_period; \ -+} -+ -+#define _STRUCT_ib_uverbs_ex_modify_cq struct { \ -+__u32 cq_handle; \ -+__u32 attr_mask; \ -+struct ib_uverbs_cq_moderation attr; \ -+__u32 reserved; \ -+} -+ -diff --git a/src/rc-compat/v37/rdma_user_ioctl_cmds.h b/src/rc-compat/v37/rdma_user_ioctl_cmds.h -new file mode 100644 -index 000000000000..38ab7accb7be ---- /dev/null -+++ b/src/rc-compat/v37/rdma_user_ioctl_cmds.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (c) 2018, Mellanox Technologies 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. -+ */ -+ -+#ifndef RDMA_USER_IOCTL_CMDS_H -+#define RDMA_USER_IOCTL_CMDS_H -+ -+#include -+#include -+ -+/* Documentation/userspace-api/ioctl/ioctl-number.rst */ -+#define RDMA_IOCTL_MAGIC 0x1b -+#define RDMA_VERBS_IOCTL \ -+ _IOWR(RDMA_IOCTL_MAGIC, 1, struct ib_uverbs_ioctl_hdr) -+ -+enum { -+ /* User input */ -+ UVERBS_ATTR_F_MANDATORY = 1U << 0, -+ /* -+ * Valid output bit should be ignored and considered set in -+ * mandatory fields. This bit is kernel output. -+ */ -+ UVERBS_ATTR_F_VALID_OUTPUT = 1U << 1, -+}; -+ -+struct ib_uverbs_attr { -+ __u16 attr_id; /* command specific type attribute */ -+ __u16 len; /* only for pointers and IDRs array */ -+ __u16 flags; /* combination of UVERBS_ATTR_F_XXXX */ -+ union { -+ struct { -+ __u8 elem_id; -+ __u8 reserved; -+ } enum_data; -+ __u16 reserved; -+ } attr_data; -+ union { -+ /* -+ * ptr to command, inline data, idr/fd or -+ * ptr to __u32 array of IDRs -+ */ -+ __aligned_u64 data; -+ /* Used by FD_IN and FD_OUT */ -+ __s64 data_s64; -+ }; -+}; -+ -+struct ib_uverbs_ioctl_hdr { -+ __u16 length; -+ __u16 object_id; -+ __u16 method_id; -+ __u16 num_attrs; -+ __aligned_u64 reserved1; -+ __u32 driver_id; -+ __u32 reserved2; -+ struct ib_uverbs_attr attrs[0]; -+}; -+ -+#endif -diff --git a/src/rc-compat/v37/util/cl_qmap.h b/src/rc-compat/v37/util/cl_qmap.h -new file mode 100644 -index 000000000000..1a800f2c8fec ---- /dev/null -+++ b/src/rc-compat/v37/util/cl_qmap.h -@@ -0,0 +1,970 @@ -+/* -+ * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved. -+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. -+ * Copyright (c) 1996-2003 Intel 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. -+ * -+ */ -+ -+/* -+ * Abstract: -+ * Declaration of quick map, a binary tree where the caller always provides -+ * all necessary storage. -+ */ -+ -+#ifndef _CL_QMAP_H_ -+#define _CL_QMAP_H_ -+ -+#include -+#include -+#include -+#include -+ -+typedef struct _cl_list_item { -+ struct _cl_list_item *p_next; -+ struct _cl_list_item *p_prev; -+} cl_list_item_t; -+ -+typedef struct _cl_pool_item { -+ cl_list_item_t list_item; -+} cl_pool_item_t; -+ -+/****h* Component Library/Quick Map -+* NAME -+* Quick Map -+* -+* DESCRIPTION -+* Quick map implements a binary tree that stores user provided cl_map_item_t -+* structures. Each item stored in a quick map has a unique 64-bit key -+* (duplicates are not allowed). Quick map provides the ability to -+* efficiently search for an item given a key. -+* -+* Quick map does not allocate any memory, and can therefore not fail -+* any operations due to insufficient memory. Quick map can thus be useful -+* in minimizing the error paths in code. -+* -+* Quick map is not thread safe, and users must provide serialization when -+* adding and removing items from the map. -+* -+* The quick map functions operate on a cl_qmap_t structure which should be -+* treated as opaque and should be manipulated only through the provided -+* functions. -+* -+* SEE ALSO -+* Structures: -+* cl_qmap_t, cl_map_item_t, cl_map_obj_t -+* -+* Callbacks: -+* cl_pfn_qmap_apply_t -+* -+* Item Manipulation: -+* cl_qmap_set_obj, cl_qmap_obj, cl_qmap_key -+* -+* Initialization: -+* cl_qmap_init -+* -+* Iteration: -+* cl_qmap_end, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_prev -+* -+* Manipulation: -+* cl_qmap_insert, cl_qmap_get, cl_qmap_remove_item, cl_qmap_remove, -+* cl_qmap_remove_all, cl_qmap_merge, cl_qmap_delta, cl_qmap_get_next -+* -+* Search: -+* cl_qmap_apply_func -+* -+* Attributes: -+* cl_qmap_count, cl_is_qmap_empty, -+*********/ -+/****i* Component Library: Quick Map/cl_map_color_t -+* NAME -+* cl_map_color_t -+* -+* DESCRIPTION -+* The cl_map_color_t enumerated type is used to note the color of -+* nodes in a map. -+* -+* SYNOPSIS -+*/ -+typedef enum _cl_map_color { -+ CL_MAP_RED, -+ CL_MAP_BLACK -+} cl_map_color_t; -+/* -+* VALUES -+* CL_MAP_RED -+* The node in the map is red. -+* -+* CL_MAP_BLACK -+* The node in the map is black. -+* -+* SEE ALSO -+* Quick Map, cl_map_item_t -+*********/ -+ -+/****s* Component Library: Quick Map/cl_map_item_t -+* NAME -+* cl_map_item_t -+* -+* DESCRIPTION -+* The cl_map_item_t structure is used by maps to store objects. -+* -+* The cl_map_item_t structure should be treated as opaque and should -+* be manipulated only through the provided functions. -+* -+* SYNOPSIS -+*/ -+typedef struct _cl_map_item { -+ /* Must be first to allow casting. */ -+ cl_pool_item_t pool_item; -+ struct _cl_map_item *p_left; -+ struct _cl_map_item *p_right; -+ struct _cl_map_item *p_up; -+ cl_map_color_t color; -+ uint64_t key; -+#ifdef _DEBUG_ -+ struct _cl_qmap *p_map; -+#endif -+} cl_map_item_t; -+/* -+* FIELDS -+* pool_item -+* Used to store the item in a doubly linked list, allowing more -+* efficient map traversal. -+* -+* p_left -+* Pointer to the map item that is a child to the left of the node. -+* -+* p_right -+* Pointer to the map item that is a child to the right of the node. -+* -+* p_up -+* Pointer to the map item that is the parent of the node. -+* -+* color -+* Indicates whether a node is red or black in the map. -+* -+* key -+* Value that uniquely represents a node in a map. This value is -+* set by calling cl_qmap_insert and can be retrieved by calling -+* cl_qmap_key. -+* -+* NOTES -+* None of the fields of this structure should be manipulated by users, as -+* they are crititcal to the proper operation of the map in which they -+* are stored. -+* -+* To allow storing items in either a quick list, a quick pool, or a quick -+* map, the map implementation guarantees that the map item can be safely -+* cast to a pool item used for storing an object in a quick pool, or cast -+* to a list item used for storing an object in a quick list. This removes -+* the need to embed a map item, a list item, and a pool item in objects -+* that need to be stored in a quick list, a quick pool, and a quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_insert, cl_qmap_key, cl_pool_item_t, cl_list_item_t -+*********/ -+ -+/****s* Component Library: Quick Map/cl_map_obj_t -+* NAME -+* cl_map_obj_t -+* -+* DESCRIPTION -+* The cl_map_obj_t structure is used to store objects in maps. -+* -+* The cl_map_obj_t structure should be treated as opaque and should -+* be manipulated only through the provided functions. -+* -+* SYNOPSIS -+*/ -+typedef struct _cl_map_obj { -+ cl_map_item_t item; -+ const void *p_object; -+} cl_map_obj_t; -+/* -+* FIELDS -+* item -+* Map item used by internally by the map to store an object. -+* -+* p_object -+* User defined context. Users should not access this field directly. -+* Use cl_qmap_set_obj and cl_qmap_obj to set and retrieve the value -+* of this field. -+* -+* NOTES -+* None of the fields of this structure should be manipulated by users, as -+* they are crititcal to the proper operation of the map in which they -+* are stored. -+* -+* Use cl_qmap_set_obj and cl_qmap_obj to set and retrieve the object -+* stored in a map item, respectively. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_set_obj, cl_qmap_obj, cl_map_item_t -+*********/ -+ -+/****s* Component Library: Quick Map/cl_qmap_t -+* NAME -+* cl_qmap_t -+* -+* DESCRIPTION -+* Quick map structure. -+* -+* The cl_qmap_t structure should be treated as opaque and should -+* be manipulated only through the provided functions. -+* -+* SYNOPSIS -+*/ -+typedef struct _cl_qmap { -+ cl_map_item_t root; -+ cl_map_item_t nil; -+ size_t count; -+} cl_qmap_t; -+/* -+* PARAMETERS -+* root -+* Map item that serves as root of the map. The root is set up to -+* always have itself as parent. The left pointer is set to point -+* to the item at the root. -+* -+* nil -+* Map item that serves as terminator for all leaves, as well as -+* providing the list item used as quick list for storing map items -+* in a list for faster traversal. -+* -+* state -+* State of the map, used to verify that operations are permitted. -+* -+* count -+* Number of items in the map. -+* -+* SEE ALSO -+* Quick Map -+*********/ -+ -+/****d* Component Library: Quick Map/cl_pfn_qmap_apply_t -+* NAME -+* cl_pfn_qmap_apply_t -+* -+* DESCRIPTION -+* The cl_pfn_qmap_apply_t function type defines the prototype for -+* functions used to iterate items in a quick map. -+* -+* SYNOPSIS -+*/ -+typedef void -+ (*cl_pfn_qmap_apply_t) (cl_map_item_t * const p_map_item, void *context); -+/* -+* PARAMETERS -+* p_map_item -+* [in] Pointer to a cl_map_item_t structure. -+* -+* context -+* [in] Value passed to the callback function. -+* -+* RETURN VALUE -+* This function does not return a value. -+* -+* NOTES -+* This function type is provided as function prototype reference for the -+* function provided by users as a parameter to the cl_qmap_apply_func -+* function. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_apply_func -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_count -+* NAME -+* cl_qmap_count -+* -+* DESCRIPTION -+* The cl_qmap_count function returns the number of items stored -+* in a quick map. -+* -+* SYNOPSIS -+*/ -+static inline uint32_t cl_qmap_count(const cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ return ((uint32_t) p_map->count); -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure whose item count to return. -+* -+* RETURN VALUE -+* Returns the number of items stored in the map. -+* -+* SEE ALSO -+* Quick Map, cl_is_qmap_empty -+*********/ -+ -+/****f* Component Library: Quick Map/cl_is_qmap_empty -+* NAME -+* cl_is_qmap_empty -+* -+* DESCRIPTION -+* The cl_is_qmap_empty function returns whether a quick map is empty. -+* -+* SYNOPSIS -+*/ -+static inline bool cl_is_qmap_empty(const cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ -+ return (p_map->count == 0); -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure to test for emptiness. -+* -+* RETURN VALUES -+* TRUE if the quick map is empty. -+* -+* FALSE otherwise. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_count, cl_qmap_remove_all -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_set_obj -+* NAME -+* cl_qmap_set_obj -+* -+* DESCRIPTION -+* The cl_qmap_set_obj function sets the object stored in a map object. -+* -+* SYNOPSIS -+*/ -+static inline void -+cl_qmap_set_obj(cl_map_obj_t * const p_map_obj, -+ const void *const p_object) -+{ -+ assert(p_map_obj); -+ p_map_obj->p_object = p_object; -+} -+ -+/* -+* PARAMETERS -+* p_map_obj -+* [in] Pointer to a map object stucture whose object pointer -+* is to be set. -+* -+* p_object -+* [in] User defined context. -+* -+* RETURN VALUE -+* This function does not return a value. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_obj -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_obj -+* NAME -+* cl_qmap_obj -+* -+* DESCRIPTION -+* The cl_qmap_obj function returns the object stored in a map object. -+* -+* SYNOPSIS -+*/ -+static inline void *cl_qmap_obj(const cl_map_obj_t * const p_map_obj) -+{ -+ assert(p_map_obj); -+ return ((void *)p_map_obj->p_object); -+} -+ -+/* -+* PARAMETERS -+* p_map_obj -+* [in] Pointer to a map object stucture whose object pointer to return. -+* -+* RETURN VALUE -+* Returns the value of the object pointer stored in the map object. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_set_obj -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_key -+* NAME -+* cl_qmap_key -+* -+* DESCRIPTION -+* The cl_qmap_key function retrieves the key value of a map item. -+* -+* SYNOPSIS -+*/ -+static inline uint64_t cl_qmap_key(const cl_map_item_t * const p_item) -+{ -+ assert(p_item); -+ return (p_item->key); -+} -+ -+/* -+* PARAMETERS -+* p_item -+* [in] Pointer to a map item whose key value to return. -+* -+* RETURN VALUE -+* Returns the 64-bit key value for the specified map item. -+* -+* NOTES -+* The key value is set in a call to cl_qmap_insert. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_insert -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_init -+* NAME -+* cl_qmap_init -+* -+* DESCRIPTION -+* The cl_qmap_init function initialized a quick map for use. -+* -+* SYNOPSIS -+*/ -+void cl_qmap_init(cl_qmap_t * const p_map); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure to initialize. -+* -+* RETURN VALUES -+* This function does not return a value. -+* -+* NOTES -+* Allows calling quick map manipulation functions. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_insert, cl_qmap_remove -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_end -+* NAME -+* cl_qmap_end -+* -+* DESCRIPTION -+* The cl_qmap_end function returns the end of a quick map. -+* -+* SYNOPSIS -+*/ -+static inline const cl_map_item_t *cl_qmap_end(const cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ /* Nil is the end of the map. */ -+ return (&p_map->nil); -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure whose end to return. -+* -+* RETURN VALUE -+* Pointer to the end of the map. -+* -+* NOTES -+* cl_qmap_end is useful for determining the validity of map items returned -+* by cl_qmap_head, cl_qmap_tail, cl_qmap_next, or cl_qmap_prev. If the -+* map item pointer returned by any of these functions compares to the end, -+* the end of the map was encoutered. -+* When using cl_qmap_head or cl_qmap_tail, this condition indicates that -+* the map is empty. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_prev -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_head -+* NAME -+* cl_qmap_head -+* -+* DESCRIPTION -+* The cl_qmap_head function returns the map item with the lowest key -+* value stored in a quick map. -+* -+* SYNOPSIS -+*/ -+static inline cl_map_item_t *cl_qmap_head(const cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ return ((cl_map_item_t *) p_map->nil.pool_item.list_item.p_next); -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure whose item with the lowest -+* key is returned. -+* -+* RETURN VALUES -+* Pointer to the map item with the lowest key in the quick map. -+* -+* Pointer to the map end if the quick map was empty. -+* -+* NOTES -+* cl_qmap_head does not remove the item from the map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_tail, cl_qmap_next, cl_qmap_prev, cl_qmap_end, -+* cl_qmap_item_t -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_tail -+* NAME -+* cl_qmap_tail -+* -+* DESCRIPTION -+* The cl_qmap_tail function returns the map item with the highest key -+* value stored in a quick map. -+* -+* SYNOPSIS -+*/ -+static inline cl_map_item_t *cl_qmap_tail(const cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ return ((cl_map_item_t *) p_map->nil.pool_item.list_item.p_prev); -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure whose item with the -+* highest key is returned. -+* -+* RETURN VALUES -+* Pointer to the map item with the highest key in the quick map. -+* -+* Pointer to the map end if the quick map was empty. -+* -+* NOTES -+* cl_qmap_end does not remove the item from the map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_head, cl_qmap_next, cl_qmap_prev, cl_qmap_end, -+* cl_qmap_item_t -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_next -+* NAME -+* cl_qmap_next -+* -+* DESCRIPTION -+* The cl_qmap_next function returns the map item with the next higher -+* key value than a specified map item. -+* -+* SYNOPSIS -+*/ -+static inline cl_map_item_t *cl_qmap_next(const cl_map_item_t * const p_item) -+{ -+ assert(p_item); -+ return ((cl_map_item_t *) p_item->pool_item.list_item.p_next); -+} -+ -+/* -+* PARAMETERS -+* p_item -+* [in] Pointer to a map item whose successor to return. -+* -+* RETURN VALUES -+* Pointer to the map item with the next higher key value in a quick map. -+* -+* Pointer to the map end if the specified item was the last item in -+* the quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_prev, cl_qmap_end, -+* cl_map_item_t -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_prev -+* NAME -+* cl_qmap_prev -+* -+* DESCRIPTION -+* The cl_qmap_prev function returns the map item with the next lower -+* key value than a precified map item. -+* -+* SYNOPSIS -+*/ -+static inline cl_map_item_t *cl_qmap_prev(const cl_map_item_t * const p_item) -+{ -+ assert(p_item); -+ return ((cl_map_item_t *) p_item->pool_item.list_item.p_prev); -+} -+ -+/* -+* PARAMETERS -+* p_item -+* [in] Pointer to a map item whose predecessor to return. -+* -+* RETURN VALUES -+* Pointer to the map item with the next lower key value in a quick map. -+* -+* Pointer to the map end if the specifid item was the first item in -+* the quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_end, -+* cl_map_item_t -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_insert -+* NAME -+* cl_qmap_insert -+* -+* DESCRIPTION -+* The cl_qmap_insert function inserts a map item into a quick map. -+* NOTE: Only if such a key does not alerady exist in the map !!!! -+* -+* SYNOPSIS -+*/ -+cl_map_item_t *cl_qmap_insert(cl_qmap_t * const p_map, -+ const uint64_t key, -+ cl_map_item_t * const p_item); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure into which to add the item. -+* -+* key -+* [in] Value to assign to the item. -+* -+* p_item -+* [in] Pointer to a cl_map_item_t stucture to insert into the quick map. -+* -+* RETURN VALUE -+* Pointer to the item in the map with the specified key. If insertion -+* was successful, this is the pointer to the item. If an item with the -+* specified key already exists in the map, the pointer to that item is -+* returned - but the new key is NOT inserted... -+* -+* NOTES -+* Insertion operations may cause the quick map to rebalance. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_remove, cl_map_item_t -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_get -+* NAME -+* cl_qmap_get -+* -+* DESCRIPTION -+* The cl_qmap_get function returns the map item associated with a key. -+* -+* SYNOPSIS -+*/ -+cl_map_item_t *cl_qmap_get(const cl_qmap_t * const p_map, -+ const uint64_t key); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure from which to retrieve the -+* item with the specified key. -+* -+* key -+* [in] Key value used to search for the desired map item. -+* -+* RETURN VALUES -+* Pointer to the map item with the desired key value. -+* -+* Pointer to the map end if there was no item with the desired key value -+* stored in the quick map. -+* -+* NOTES -+* cl_qmap_get does not remove the item from the quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_get_next, cl_qmap_remove -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_get_next -+* NAME -+* cl_qmap_get_next -+* -+* DESCRIPTION -+* The cl_qmap_get_next function returns the first map item associated with a -+* key > the key specified. -+* -+* SYNOPSIS -+*/ -+cl_map_item_t *cl_qmap_get_next(const cl_qmap_t * const p_map, -+ const uint64_t key); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure from which to retrieve the -+* first item with a key > the specified key. -+* -+* key -+* [in] Key value used to search for the desired map item. -+* -+* RETURN VALUES -+* Pointer to the first map item with a key > the desired key value. -+* -+* Pointer to the map end if there was no item with a key > the desired key -+* value stored in the quick map. -+* -+* NOTES -+* cl_qmap_get_next does not remove the item from the quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_get, cl_qmap_remove -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_remove_item -+* NAME -+* cl_qmap_remove_item -+* -+* DESCRIPTION -+* The cl_qmap_remove_item function removes the specified map item -+* from a quick map. -+* -+* SYNOPSIS -+*/ -+void -+cl_qmap_remove_item(cl_qmap_t * const p_map, -+ cl_map_item_t * const p_item); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure from which to -+* remove item. -+* -+* p_item -+* [in] Pointer to a map item to remove from its quick map. -+* -+* RETURN VALUES -+* This function does not return a value. -+* -+* In a debug build, cl_qmap_remove_item asserts that the item being removed -+* is in the specified map. -+* -+* NOTES -+* Removes the map item pointed to by p_item from its quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_remove, cl_qmap_remove_all, cl_qmap_insert -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_remove -+* NAME -+* cl_qmap_remove -+* -+* DESCRIPTION -+* The cl_qmap_remove function removes the map item with the specified key -+* from a quick map. -+* -+* SYNOPSIS -+*/ -+cl_map_item_t *cl_qmap_remove(cl_qmap_t * const p_map, -+ const uint64_t key); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure from which to remove the item -+* with the specified key. -+* -+* key -+* [in] Key value used to search for the map item to remove. -+* -+* RETURN VALUES -+* Pointer to the removed map item if it was found. -+* -+* Pointer to the map end if no item with the specified key exists in the -+* quick map. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_remove_item, cl_qmap_remove_all, cl_qmap_insert -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_remove_all -+* NAME -+* cl_qmap_remove_all -+* -+* DESCRIPTION -+* The cl_qmap_remove_all function removes all items in a quick map, -+* leaving it empty. -+* -+* SYNOPSIS -+*/ -+static inline void cl_qmap_remove_all(cl_qmap_t * const p_map) -+{ -+ assert(p_map); -+ -+ p_map->root.p_left = &p_map->nil; -+ p_map->nil.pool_item.list_item.p_next = &p_map->nil.pool_item.list_item; -+ p_map->nil.pool_item.list_item.p_prev = &p_map->nil.pool_item.list_item; -+ p_map->count = 0; -+} -+ -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure to empty. -+* -+* RETURN VALUES -+* This function does not return a value. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_remove, cl_qmap_remove_item -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_merge -+* NAME -+* cl_qmap_merge -+* -+* DESCRIPTION -+* The cl_qmap_merge function moves all items from one map to another, -+* excluding duplicates. -+* -+* SYNOPSIS -+*/ -+void -+cl_qmap_merge(cl_qmap_t * const p_dest_map, -+ cl_qmap_t * const p_src_map); -+/* -+* PARAMETERS -+* p_dest_map -+* [out] Pointer to a cl_qmap_t structure to which items should be added. -+* -+* p_src_map -+* [in/out] Pointer to a cl_qmap_t structure whose items to add -+* to p_dest_map. -+* -+* RETURN VALUES -+* This function does not return a value. -+* -+* NOTES -+* Items are evaluated based on their keys only. -+* -+* Upon return from cl_qmap_merge, the quick map referenced by p_src_map -+* contains all duplicate items. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_delta -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_delta -+* NAME -+* cl_qmap_delta -+* -+* DESCRIPTION -+* The cl_qmap_delta function computes the differences between two maps. -+* -+* SYNOPSIS -+*/ -+void -+cl_qmap_delta(cl_qmap_t * const p_map1, -+ cl_qmap_t * const p_map2, -+ cl_qmap_t * const p_new, cl_qmap_t * const p_old); -+/* -+* PARAMETERS -+* p_map1 -+* [in/out] Pointer to the first of two cl_qmap_t structures whose -+* differences to compute. -+* -+* p_map2 -+* [in/out] Pointer to the second of two cl_qmap_t structures whose -+* differences to compute. -+* -+* p_new -+* [out] Pointer to an empty cl_qmap_t structure that contains the -+* items unique to p_map2 upon return from the function. -+* -+* p_old -+* [out] Pointer to an empty cl_qmap_t structure that contains the -+* items unique to p_map1 upon return from the function. -+* -+* RETURN VALUES -+* This function does not return a value. -+* -+* NOTES -+* Items are evaluated based on their keys. Items that exist in both -+* p_map1 and p_map2 remain in their respective maps. Items that -+* exist only p_map1 are moved to p_old. Likewise, items that exist only -+* in p_map2 are moved to p_new. This function can be useful in evaluating -+* changes between two maps. -+* -+* Both maps pointed to by p_new and p_old must be empty on input. This -+* requirement removes the possibility of failures. -+* -+* SEE ALSO -+* Quick Map, cl_qmap_merge -+*********/ -+ -+/****f* Component Library: Quick Map/cl_qmap_apply_func -+* NAME -+* cl_qmap_apply_func -+* -+* DESCRIPTION -+* The cl_qmap_apply_func function executes a specified function -+* for every item stored in a quick map. -+* -+* SYNOPSIS -+*/ -+void -+cl_qmap_apply_func(const cl_qmap_t * const p_map, -+ cl_pfn_qmap_apply_t pfn_func, -+ const void *const context); -+/* -+* PARAMETERS -+* p_map -+* [in] Pointer to a cl_qmap_t structure. -+* -+* pfn_func -+* [in] Function invoked for every item in the quick map. -+* See the cl_pfn_qmap_apply_t function type declaration for -+* details about the callback function. -+* -+* context -+* [in] Value to pass to the callback functions to provide context. -+* -+* RETURN VALUE -+* This function does not return a value. -+* -+* NOTES -+* The function provided must not perform any map operations, as these -+* would corrupt the quick map. -+* -+* SEE ALSO -+* Quick Map, cl_pfn_qmap_apply_t -+*********/ -+ -+#endif /* _CL_QMAP_H_ */ -diff --git a/src/rc-compat/v37/util/compiler.h b/src/rc-compat/v37/util/compiler.h -new file mode 100644 -index 000000000000..dfce82f18841 ---- /dev/null -+++ b/src/rc-compat/v37/util/compiler.h -@@ -0,0 +1,54 @@ -+/* GPLv2 or OpenIB.org BSD (MIT) See COPYING file */ -+#ifndef UTIL_COMPILER_H -+#define UTIL_COMPILER_H -+ -+/* Use to tag a variable that causes compiler warnings. Use as: -+ int uninitialized_var(sz) -+ -+ This is only enabled for old compilers. gcc 6.x and beyond have excellent -+ static flow analysis. If code solicits a warning from 6.x it is almost -+ certainly too complex for a human to understand. For some reason powerpc -+ uses a different scheme than gcc for flow analysis. -+*/ -+#if (__GNUC__ >= 6 && !defined(__powerpc__)) || defined(__clang__) -+#define uninitialized_var(x) x -+#else -+#define uninitialized_var(x) x = x -+#endif -+ -+#ifndef likely -+#ifdef __GNUC__ -+#define likely(x) __builtin_expect(!!(x), 1) -+#else -+#define likely(x) (x) -+#endif -+#endif -+ -+#ifndef unlikely -+#ifdef __GNUC__ -+#define unlikely(x) __builtin_expect(!!(x), 0) -+#else -+#define unlikely(x) (x) -+#endif -+#endif -+ -+#ifdef HAVE_FUNC_ATTRIBUTE_ALWAYS_INLINE -+#define ALWAYS_INLINE __attribute__((always_inline)) -+#else -+#define ALWAYS_INLINE -+#endif -+ -+/* Use to mark fall through on switch statements as desired. */ -+#if __GNUC__ >= 7 -+#define SWITCH_FALLTHROUGH __attribute__ ((fallthrough)) -+#else -+#define SWITCH_FALLTHROUGH -+#endif -+ -+#ifdef __CHECKER__ -+# define __force __attribute__((force)) -+#else -+# define __force -+#endif -+ -+#endif -diff --git a/src/rc-compat/v37/util/mmio.h b/src/rc-compat/v37/util/mmio.h -new file mode 100644 -index 000000000000..101af9dd332d ---- /dev/null -+++ b/src/rc-compat/v37/util/mmio.h -@@ -0,0 +1,267 @@ -+/* GPLv2 or OpenIB.org BSD (MIT) See COPYING file -+ -+ These accessors always map to PCI-E TLPs in predictable ways. Translation -+ to other buses should follow similar definitions. -+ -+ write32(mem, 1) -+ Produce a 4 byte MemWr TLP with bit 0 of DW byte offset 0 set -+ write32_be(mem, htobe32(1)) -+ Produce a 4 byte MemWr TLP with bit 0 of DW byte offset 3 set -+ write32_le(mem, htole32(1)) -+ Produce a 4 byte MemWr TLP with bit 0 of DW byte offset 0 set -+ -+ For ordering these accessors are similar to the Kernel's concept of -+ writel_relaxed(). When working with UC memory the following hold: -+ -+ 1) Strong ordering is required when talking to the same device (eg BAR), -+ and combining is not permitted: -+ -+ write32(mem, 1); -+ write32(mem + 4, 1); -+ write32(mem, 1); -+ -+ Must produce three TLPs, in order. -+ -+ 2) Ordering ignores all pthread locking: -+ -+ pthread_spin_lock(&lock); -+ write32(mem, global++); -+ pthread_spin_unlock(&lock); -+ -+ When run concurrently on all CPUs the device must observe all stores, -+ but the data value will not be strictly increasing. -+ -+ 3) Interaction with DMA is not ordered. Explicit use of a barrier from -+ udma_barriers is required: -+ -+ *dma_mem = 1; -+ udma_to_device_barrier(); -+ write32(mem, GO_DMA); -+ -+ 4) Access out of program order (eg speculation), either by the CPU or -+ compiler is not permitted: -+ -+ if (cond) -+ read32(); -+ -+ Must not issue a read TLP if cond is false. -+ -+ If these are used with WC memory then #1 and #4 do not apply, and all WC -+ accesses must be bracketed with mmio_wc_start() // mmio_flush_writes() -+*/ -+ -+#ifndef __UTIL_MMIO_H -+#define __UTIL_MMIO_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* The first step is to define the 'raw' accessors. To make this very safe -+ with sparse we define two versions of each, a le and a be - however the -+ code is always identical. -+*/ -+#ifdef __s390x__ -+#include -+#include -+ -+/* s390 requires a privileged instruction to access IO memory, these syscalls -+ perform that instruction using a memory buffer copy semantic. -+*/ -+static inline void s390_mmio_write(void *mmio_addr, const void *val, -+ size_t length) -+{ -+ // FIXME: Check for error and call abort? -+ syscall(__NR_s390_pci_mmio_write, mmio_addr, val, length); -+} -+ -+static inline void s390_mmio_read(const void *mmio_addr, void *val, -+ size_t length) -+{ -+ // FIXME: Check for error and call abort? -+ syscall(__NR_s390_pci_mmio_read, mmio_addr, val, length); -+} -+ -+#define MAKE_WRITE(_NAME_, _SZ_) \ -+ static inline void _NAME_##_be(void *addr, __be##_SZ_ value) \ -+ { \ -+ s390_mmio_write(addr, &value, sizeof(value)); \ -+ } \ -+ static inline void _NAME_##_le(void *addr, __le##_SZ_ value) \ -+ { \ -+ s390_mmio_write(addr, &value, sizeof(value)); \ -+ } -+#define MAKE_READ(_NAME_, _SZ_) \ -+ static inline __be##_SZ_ _NAME_##_be(const void *addr) \ -+ { \ -+ __be##_SZ_ res; \ -+ s390_mmio_read(addr, &res, sizeof(res)); \ -+ return res; \ -+ } \ -+ static inline __le##_SZ_ _NAME_##_le(const void *addr) \ -+ { \ -+ __le##_SZ_ res; \ -+ s390_mmio_read(addr, &res, sizeof(res)); \ -+ return res; \ -+ } -+ -+static inline void mmio_write8(void *addr, uint8_t value) -+{ -+ s390_mmio_write(addr, &value, sizeof(value)); -+} -+ -+static inline uint8_t mmio_read8(const void *addr) -+{ -+ uint8_t res; -+ s390_mmio_read(addr, &res, sizeof(res)); -+ return res; -+} -+ -+#else /* __s390x__ */ -+ -+#define MAKE_WRITE(_NAME_, _SZ_) \ -+ static inline void _NAME_##_be(void *addr, __be##_SZ_ value) \ -+ { \ -+ atomic_store_explicit((_Atomic(uint##_SZ_##_t) *)addr, \ -+ (__force uint##_SZ_##_t)value, \ -+ memory_order_relaxed); \ -+ } \ -+ static inline void _NAME_##_le(void *addr, __le##_SZ_ value) \ -+ { \ -+ atomic_store_explicit((_Atomic(uint##_SZ_##_t) *)addr, \ -+ (__force uint##_SZ_##_t)value, \ -+ memory_order_relaxed); \ -+ } -+#define MAKE_READ(_NAME_, _SZ_) \ -+ static inline __be##_SZ_ _NAME_##_be(const void *addr) \ -+ { \ -+ return (__force __be##_SZ_)atomic_load_explicit( \ -+ (_Atomic(uint##_SZ_##_t) *)addr, memory_order_relaxed); \ -+ } \ -+ static inline __le##_SZ_ _NAME_##_le(const void *addr) \ -+ { \ -+ return (__force __le##_SZ_)atomic_load_explicit( \ -+ (_Atomic(uint##_SZ_##_t) *)addr, memory_order_relaxed); \ -+ } -+ -+static inline void mmio_write8(void *addr, uint8_t value) -+{ -+ atomic_store_explicit((_Atomic(uint8_t) *)addr, value, -+ memory_order_relaxed); -+} -+static inline uint8_t mmio_read8(const void *addr) -+{ -+ return atomic_load_explicit((_Atomic(uint32_t) *)addr, -+ memory_order_relaxed); -+} -+#endif /* __s390x__ */ -+ -+MAKE_WRITE(mmio_write16, 16) -+MAKE_WRITE(mmio_write32, 32) -+ -+MAKE_READ(mmio_read16, 16) -+MAKE_READ(mmio_read32, 32) -+ -+#if SIZEOF_LONG == 8 -+MAKE_WRITE(mmio_write64, 64) -+MAKE_READ(mmio_read64, 64) -+#else -+void mmio_write64_be(void *addr, __be64 val); -+static inline void mmio_write64_le(void *addr, __le64 val) -+{ -+ mmio_write64_be(addr, (__be64 __force)val); -+} -+ -+/* There is no way to do read64 atomically, rather than provide some sketchy -+ implementation we leave these functions undefined, users should not call -+ them if SIZEOF_LONG != 8, but instead implement an appropriate version. -+*/ -+__be64 mmio_read64_be(const void *addr); -+__le64 mmio_read64_le(const void *addr); -+#endif /* SIZEOF_LONG == 8 */ -+ -+#undef MAKE_WRITE -+#undef MAKE_READ -+ -+/* Now we can define the host endian versions of the operator, this just includes -+ a call to htole. -+*/ -+#define MAKE_WRITE(_NAME_, _SZ_) \ -+ static inline void _NAME_(void *addr, uint##_SZ_##_t value) \ -+ { \ -+ _NAME_##_le(addr, htole##_SZ_(value)); \ -+ } -+#define MAKE_READ(_NAME_, _SZ_) \ -+ static inline uint##_SZ_##_t _NAME_(const void *addr) \ -+ { \ -+ return le##_SZ_##toh(_NAME_##_le(addr)); \ -+ } -+ -+/* This strictly guarantees the order of TLP generation for the memory copy to -+ be in ascending address order. -+*/ -+#ifdef __s390x__ -+static inline void mmio_memcpy_x64(void *dest, const void *src, size_t bytecnt) -+{ -+ s390_mmio_write(dest, src, bytecnt); -+} -+#else -+ -+/* Transfer is some multiple of 64 bytes */ -+static inline void mmio_memcpy_x64(void *dest, const void *src, size_t bytecnt) -+{ -+ uintptr_t *dst_p = dest; -+ -+ /* Caller must guarantee: -+ assert(bytecnt != 0); -+ assert((bytecnt % 64) == 0); -+ assert(((uintptr_t)dest) % __alignof__(*dst) == 0); -+ assert(((uintptr_t)src) % __alignof__(*dst) == 0); -+ */ -+ -+ /* Use the native word size for the copy */ -+ if (sizeof(*dst_p) == 8) { -+ const __be64 *src_p = src; -+ -+ do { -+ /* Do 64 bytes at a time */ -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ mmio_write64_be(dst_p++, *src_p++); -+ -+ bytecnt -= 8 * sizeof(*dst_p); -+ } while (bytecnt > 0); -+ } else if (sizeof(*dst_p) == 4) { -+ const __be32 *src_p = src; -+ -+ do { -+ mmio_write32_be(dst_p++, *src_p++); -+ mmio_write32_be(dst_p++, *src_p++); -+ bytecnt -= 2 * sizeof(*dst_p); -+ } while (bytecnt > 0); -+ } -+} -+#endif -+ -+MAKE_WRITE(mmio_write16, 16) -+MAKE_WRITE(mmio_write32, 32) -+MAKE_WRITE(mmio_write64, 64) -+ -+MAKE_READ(mmio_read16, 16) -+MAKE_READ(mmio_read32, 32) -+MAKE_READ(mmio_read64, 64) -+ -+#undef MAKE_WRITE -+#undef MAKE_READ -+ -+#endif -diff --git a/src/rc-compat/v37/util/node_name_map.h b/src/rc-compat/v37/util/node_name_map.h -new file mode 100644 -index 000000000000..e78d274b116e ---- /dev/null -+++ b/src/rc-compat/v37/util/node_name_map.h -@@ -0,0 +1,19 @@ -+/* Copyright (c) 2019 Mellanox Technologies. All rights reserved. -+ * -+ * Connect to opensm's cl_nodenamemap.h if it is available. -+ */ -+#ifndef __LIBUTIL_NODE_NAME_MAP_H__ -+#define __LIBUTIL_NODE_NAME_MAP_H__ -+ -+#include -+ -+struct nn_map; -+typedef struct nn_map nn_map_t; -+ -+nn_map_t *open_node_name_map(const char *node_name_map); -+void close_node_name_map(nn_map_t *map); -+/* NOTE: parameter "nodedesc" may be modified here. */ -+char *remap_node_name(nn_map_t *map, uint64_t target_guid, char *nodedesc); -+char *clean_nodedesc(char *nodedesc); -+ -+#endif -diff --git a/src/rc-compat/v37/util/rdma_nl.h b/src/rc-compat/v37/util/rdma_nl.h -new file mode 100644 -index 000000000000..9c0916978283 ---- /dev/null -+++ b/src/rc-compat/v37/util/rdma_nl.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) 2019, Mellanox Technologies. 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. -+ */ -+#ifndef UTIL_RDMA_NL_H -+#define UTIL_RDMA_NL_H -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+extern struct nla_policy rdmanl_policy[RDMA_NLDEV_ATTR_MAX]; -+struct nl_sock *rdmanl_socket_alloc(void); -+int rdmanl_get_devices(struct nl_sock *nl, nl_recvmsg_msg_cb_t cb_func, -+ void *data); -+int rdmanl_get_chardev(struct nl_sock *nl, int ibidx, const char *name, -+ nl_recvmsg_msg_cb_t cb_func, void *data); -+bool get_copy_on_fork(void); -+int rdmanl_get_copy_on_fork(struct nl_sock *nl, nl_recvmsg_msg_cb_t cb_func, -+ void *data); -+ -+#endif -diff --git a/src/rc-compat/v37/util/symver.h b/src/rc-compat/v37/util/symver.h -new file mode 100644 -index 000000000000..eb14c57ebdc1 ---- /dev/null -+++ b/src/rc-compat/v37/util/symver.h -@@ -0,0 +1,107 @@ -+/* GPLv2 or OpenIB.org BSD (MIT) See COPYING file -+ -+ These definitions help using the ELF symbol version feature, and must be -+ used in conjunction with the library's map file. -+ */ -+ -+#ifndef __UTIL_SYMVER_H -+#define __UTIL_SYMVER_H -+ -+#include -+#include -+ -+/* -+ These macros should only be used if the library is defining compatibility -+ symbols, eg: -+ -+ 213: 000000000000a650 315 FUNC GLOBAL DEFAULT 13 ibv_get_device_list@IBVERBS_1.0 -+ 214: 000000000000b020 304 FUNC GLOBAL DEFAULT 13 ibv_get_device_list@@IBVERBS_1.1 -+ -+ Symbols which have only a single implementation should use a normal extern -+ function and be placed in the correct stanza in the linker map file. -+ -+ Follow this pattern to use this feature: -+ public.h: -+ struct ibv_device **ibv_get_device_list(int *num_devices); -+ foo.c: -+ // Implement the latest version -+ LATEST_SYMVER_FUNC(ibv_get_device_list, 1_1, "IBVERBS_1.1", -+ struct ibv_device **, -+ int *num_devices) -+ { -+ ... -+ } -+ -+ // Implement the compat version -+ COMPAT_SYMVER_FUNC(ibv_get_device_list, 1_0, "IBVERBS_1.0", -+ struct ibv_device_1_0 **, -+ int *num_devices) -+ { -+ ... -+ } -+ -+ As well as matching information in the map file. -+ -+ These macros deal with the various uglyness in gcc surrounding symbol -+ versions -+ -+ - The internal name __public_1_x is synthesized by the macro -+ - A prototype for the internal name is created by the macro -+ - If statically linking the latest symbol expands into a normal function -+ definition -+ - If statically linking the compat symbols expand into unused static -+ functions are are discarded by the compiler. -+ - The prototype of the latest symbol is checked against the public -+ prototype (only when compiling statically) -+ -+ The extra prototypes are included only to avoid -Wmissing-prototypes -+ warnings. See also Documentation/versioning.md -+*/ -+ -+#if HAVE_FUNC_ATTRIBUTE_SYMVER -+#define _MAKE_SYMVER(_local_sym, _public_sym, _ver_str) \ -+ __attribute__((__symver__(#_public_sym "@" _ver_str))) -+#else -+#define _MAKE_SYMVER(_local_sym, _public_sym, _ver_str) \ -+ asm(".symver " #_local_sym "," #_public_sym "@" _ver_str); -+#endif -+#define _MAKE_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ _ret __##_public_sym##_##_uniq(__VA_ARGS__); \ -+ _MAKE_SYMVER(__##_public_sym##_##_uniq, _public_sym, _ver_str) \ -+ _ret __##_public_sym##_##_uniq(__VA_ARGS__) -+ -+#if defined(HAVE_FULL_SYMBOL_VERSIONS) && !defined(_STATIC_LIBRARY_BUILD_) -+ -+ // Produce all symbol versions for dynamic linking -+ -+# define COMPAT_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ _MAKE_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, __VA_ARGS__) -+# define LATEST_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ _MAKE_SYMVER_FUNC(_public_sym, _uniq, "@" _ver_str, _ret, __VA_ARGS__) -+ -+#elif defined(HAVE_LIMITED_SYMBOL_VERSIONS) && !defined(_STATIC_LIBRARY_BUILD_) -+ -+ /* Produce only implemenations for the latest symbol and tag it with the -+ * correct symbol versions. This supports dynamic linkers that do not -+ * understand symbol versions -+ */ -+# define COMPAT_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ static inline _ret __##_public_sym##_##_uniq(__VA_ARGS__) -+# define LATEST_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ _MAKE_SYMVER_FUNC(_public_sym, _uniq, "@" _ver_str, _ret, __VA_ARGS__) -+ -+#else -+ -+ // Static linking, or linker does not support symbol versions -+#define COMPAT_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ static inline __attribute__((unused)) \ -+ _ret __##_public_sym##_##_uniq(__VA_ARGS__) -+#define LATEST_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...) \ -+ static __attribute__((unused)) \ -+ _ret __##_public_sym##_##_uniq(__VA_ARGS__) \ -+ __attribute__((alias(stringify(_public_sym)))); \ -+ extern _ret _public_sym(__VA_ARGS__) -+ -+#endif -+ -+#endif -diff --git a/src/rc-compat/v37/util/udma_barrier.h b/src/rc-compat/v37/util/udma_barrier.h -new file mode 100644 -index 000000000000..5730576e6356 ---- /dev/null -+++ b/src/rc-compat/v37/util/udma_barrier.h -@@ -0,0 +1,267 @@ -+/* -+ * Copyright (c) 2005 Topspin Communications. 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. -+ */ -+ -+#ifndef __UTIL_UDMA_BARRIER_H -+#define __UTIL_UDMA_BARRIER_H -+ -+#include -+ -+/* Barriers for DMA. -+ -+ These barriers are expliclty only for use with user DMA operations. If you -+ are looking for barriers to use with cache-coherent multi-threaded -+ consitency then look in stdatomic.h. If you need both kinds of synchronicity -+ for the same address then use an atomic operation followed by one -+ of these barriers. -+ -+ When reasoning about these barriers there are two objects: -+ - CPU attached address space (the CPU memory could be a range of things: -+ cached/uncached/non-temporal CPU DRAM, uncached MMIO space in another -+ device, pMEM). Generally speaking the ordering is only relative -+ to the local CPU's view of the system. Eg if the local CPU -+ is not guaranteed to see a write from another CPU then it is also -+ OK for the DMA device to also not see the write after the barrier. -+ - A DMA initiator on a bus. For instance a PCI-E device issuing -+ MemRd/MemWr TLPs. -+ -+ The ordering guarantee is always stated between those two streams. Eg what -+ happens if a MemRd TLP is sent in via PCI-E relative to a CPU WRITE to the -+ same memory location. -+ -+ The providers have a very regular and predictable use of these barriers, -+ to make things very clear each narrow use is given a name and the proper -+ name should be used in the provider as a form of documentation. -+*/ -+ -+/* Ensure that the device's view of memory matches the CPU's view of memory. -+ This should be placed before any MMIO store that could trigger the device -+ to begin doing DMA, such as a device doorbell ring. -+ -+ eg -+ *dma_buf = 1; -+ udma_to_device_barrier(); -+ mmio_write(DO_DMA_REG, dma_buf); -+ Must ensure that the device sees the '1'. -+ -+ This is required to fence writes created by the libibverbs user. Those -+ writes could be to any CPU mapped memory object with any cachability mode. -+ -+ NOTE: x86 has historically used a weaker semantic for this barrier, and -+ only fenced normal stores to normal memory. libibverbs users using other -+ memory types or non-temporal stores are required to use SFENCE in their own -+ code prior to calling verbs to start a DMA. -+*/ -+#if defined(__i386__) -+#define udma_to_device_barrier() asm volatile("" ::: "memory") -+#elif defined(__x86_64__) -+#define udma_to_device_barrier() asm volatile("" ::: "memory") -+#elif defined(__PPC64__) -+#define udma_to_device_barrier() asm volatile("sync" ::: "memory") -+#elif defined(__PPC__) -+#define udma_to_device_barrier() asm volatile("sync" ::: "memory") -+#elif defined(__ia64__) -+#define udma_to_device_barrier() asm volatile("mf" ::: "memory") -+#elif defined(__sparc_v9__) -+#define udma_to_device_barrier() asm volatile("membar #StoreStore" ::: "memory") -+#elif defined(__aarch64__) -+#define udma_to_device_barrier() asm volatile("dsb st" ::: "memory"); -+#elif defined(__sparc__) || defined(__s390x__) -+#define udma_to_device_barrier() asm volatile("" ::: "memory") -+#elif defined(__loongarch__) -+#define udma_to_device_barrier() asm volatile("dbar 0" ::: "memory") -+#else -+#error No architecture specific memory barrier defines found! -+#endif -+ -+/* Ensure that all ordered stores from the device are observable from the -+ CPU. This only makes sense after something that observes an ordered store -+ from the device - eg by reading a MMIO register or seeing that CPU memory is -+ updated. -+ -+ This guarantees that all reads that follow the barrier see the ordered -+ stores that preceded the observation. -+ -+ For instance, this would be used after testing a valid bit in a memory -+ that is a DMA target, to ensure that the following reads see the -+ data written before the MemWr TLP that set the valid bit. -+*/ -+#if defined(__i386__) -+#define udma_from_device_barrier() asm volatile("lock; addl $0,0(%%esp) " ::: "memory") -+#elif defined(__x86_64__) -+#define udma_from_device_barrier() asm volatile("lfence" ::: "memory") -+#elif defined(__PPC64__) -+#define udma_from_device_barrier() asm volatile("lwsync" ::: "memory") -+#elif defined(__PPC__) -+#define udma_from_device_barrier() asm volatile("sync" ::: "memory") -+#elif defined(__ia64__) -+#define udma_from_device_barrier() asm volatile("mf" ::: "memory") -+#elif defined(__sparc_v9__) -+#define udma_from_device_barrier() asm volatile("membar #LoadLoad" ::: "memory") -+#elif defined(__aarch64__) -+#define udma_from_device_barrier() asm volatile("dsb ld" ::: "memory"); -+#elif defined(__sparc__) || defined(__s390x__) -+#define udma_from_device_barrier() asm volatile("" ::: "memory") -+#elif defined(__loongarch__) -+#define udma_from_device_barrier() asm volatile("dbar 0" ::: "memory") -+#else -+#error No architecture specific memory barrier defines found! -+#endif -+ -+/* Order writes to CPU memory so that a DMA device cannot view writes after -+ the barrier without also seeing all writes before the barrier. This does -+ not guarantee any writes are visible to DMA. -+ -+ This would be used in cases where a DMA buffer might have a valid bit and -+ data, this barrier is placed after writing the data but before writing the -+ valid bit to ensure the DMA device cannot observe a set valid bit with -+ unwritten data. -+ -+ Compared to udma_to_device_barrier() this barrier is not required to fence -+ anything but normal stores to normal malloc memory. Usage should be: -+ -+ write_wqe -+ udma_to_device_barrier(); // Get user memory ready for DMA -+ wqe->addr = ...; -+ wqe->flags = ...; -+ udma_ordering_write_barrier(); // Guarantee WQE written in order -+ wqe->valid = 1; -+*/ -+#define udma_ordering_write_barrier() udma_to_device_barrier() -+ -+/* Promptly flush writes to MMIO Write Cominbing memory. -+ This should be used after a write to WC memory. This is both a barrier -+ and a hint to the CPU to flush any buffers to reduce latency to TLP -+ generation. -+ -+ This is not required to have any effect on CPU memory. -+ -+ If done while holding a lock then the ordering of MMIO writes across CPUs -+ must be guaranteed to follow the natural ordering implied by the lock. -+ -+ This must also act as a barrier that prevents write combining, eg -+ *wc_mem = 1; -+ mmio_flush_writes(); -+ *wc_mem = 2; -+ Must always produce two MemWr TLPs, '1' and '2'. Without the barrier -+ the CPU is allowed to produce a single TLP '2'. -+ -+ Note that there is no order guarantee for writes to WC memory without -+ barriers. -+ -+ This is intended to be used in conjunction with WC memory to generate large -+ PCI-E MemWr TLPs from the CPU. -+*/ -+#if defined(__i386__) -+#define mmio_flush_writes() asm volatile("lock; addl $0,0(%%esp) " ::: "memory") -+#elif defined(__x86_64__) -+#define mmio_flush_writes() asm volatile("sfence" ::: "memory") -+#elif defined(__PPC64__) -+#define mmio_flush_writes() asm volatile("sync" ::: "memory") -+#elif defined(__PPC__) -+#define mmio_flush_writes() asm volatile("sync" ::: "memory") -+#elif defined(__ia64__) -+#define mmio_flush_writes() asm volatile("fwb" ::: "memory") -+#elif defined(__sparc_v9__) -+#define mmio_flush_writes() asm volatile("membar #StoreStore" ::: "memory") -+#elif defined(__aarch64__) -+#define mmio_flush_writes() asm volatile("dsb st" ::: "memory"); -+#elif defined(__sparc__) || defined(__s390x__) -+#define mmio_flush_writes() asm volatile("" ::: "memory") -+#elif defined(__loongarch__) -+#define mmio_flush_writes() asm volatile("dbar 0" ::: "memory") -+#else -+#error No architecture specific memory barrier defines found! -+#endif -+ -+/* Prevent WC writes from being re-ordered relative to other MMIO -+ writes. This should be used before a write to WC memory. -+ -+ This must act as a barrier to prevent write re-ordering from different -+ memory types: -+ *mmio_mem = 1; -+ mmio_flush_writes(); -+ *wc_mem = 2; -+ Must always produce a TLP '1' followed by '2'. -+ -+ This barrier implies udma_to_device_barrier() -+ -+ This is intended to be used in conjunction with WC memory to generate large -+ PCI-E MemWr TLPs from the CPU. -+*/ -+#define mmio_wc_start() mmio_flush_writes() -+ -+/* Keep MMIO writes in order. -+ Currently we lack writel macros that universally guarantee MMIO -+ writes happen in order, like the kernel does. Even worse many -+ providers haphazardly open code writes to MMIO memory omitting even -+ volatile. -+ -+ Until this can be fixed with a proper writel macro, this barrier -+ is a stand in to indicate places where MMIO writes should be switched -+ to some future writel. -+*/ -+#define mmio_ordered_writes_hack() mmio_flush_writes() -+ -+/* Write Combining Spinlock primitive -+ -+ Any access to a multi-value WC region must ensure that multiple cpus do not -+ write to the same values concurrently, these macros make that -+ straightforward and efficient if the choosen exclusion is a spinlock. -+ -+ The spinlock guarantees that the WC writes issued within the critical -+ section are made visible as TLP to the device. The TLP must be seen by the -+ device strictly in the order that the spinlocks are acquired, and combining -+ WC writes between different sections is not permitted. -+ -+ Use of these macros allow the fencing inside the spinlock to be combined -+ with the fencing required for DMA. -+ */ -+static inline void mmio_wc_spinlock(pthread_spinlock_t *lock) -+{ -+ pthread_spin_lock(lock); -+#if !defined(__i386__) && !defined(__x86_64__) -+ /* For x86 the serialization within the spin lock is enough to -+ * strongly order WC and other memory types. */ -+ mmio_wc_start(); -+#endif -+} -+ -+static inline void mmio_wc_spinunlock(pthread_spinlock_t *lock) -+{ -+ /* It is possible that on x86 the atomic in the lock is strong enough -+ * to force-flush the WC buffers quickly, and this SFENCE can be -+ * omitted too. */ -+ mmio_flush_writes(); -+ pthread_spin_unlock(lock); -+} -+ -+#endif -diff --git a/src/rc-compat/v37/util/util.h b/src/rc-compat/v37/util/util.h -new file mode 100644 -index 000000000000..45f50658519a ---- /dev/null -+++ b/src/rc-compat/v37/util/util.h -@@ -0,0 +1,93 @@ -+/* GPLv2 or OpenIB.org BSD (MIT) See COPYING file */ -+#ifndef UTIL_UTIL_H -+#define UTIL_UTIL_H -+ -+#include -+#include -+#include -+#include -+ -+/* Return true if the snprintf succeeded, false if there was truncation or -+ * error */ -+static inline bool __good_snprintf(size_t len, int rc) -+{ -+ return (rc < len && rc >= 0); -+} -+ -+#define check_snprintf(buf, len, fmt, ...) \ -+ __good_snprintf(len, snprintf(buf, len, fmt, ##__VA_ARGS__)) -+ -+/* a CMP b. See also the BSD macro timercmp(). */ -+#define ts_cmp(a, b, CMP) \ -+ (((a)->tv_sec == (b)->tv_sec) ? \ -+ ((a)->tv_nsec CMP (b)->tv_nsec) : \ -+ ((a)->tv_sec CMP (b)->tv_sec)) -+ -+#define offsetofend(_type, _member) \ -+ (offsetof(_type, _member) + sizeof(((_type *)0)->_member)) -+ -+#define BITS_PER_LONG (8 * sizeof(long)) -+#define BITS_PER_LONG_LONG (8 * sizeof(long long)) -+ -+#define GENMASK(h, l) \ -+ (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) -+#define GENMASK_ULL(h, l) \ -+ (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) -+ -+#define BIT(nr) (1UL << (nr)) -+#define BIT_ULL(nr) (1ULL << (nr)) -+ -+#define __bf_shf(x) (__builtin_ffsll(x) - 1) -+ -+/** -+ * FIELD_PREP() - prepare a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP() masks and shifts up the value. The result should -+ * be combined with other fields of the bitfield using logical OR. -+ */ -+#define FIELD_PREP(_mask, _val) \ -+ ({ \ -+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ -+ }) -+ -+/** -+ * FIELD_GET() - extract a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_reg: value of entire bitfield -+ * -+ * FIELD_GET() extracts the field specified by @_mask from the -+ * bitfield passed in as @_reg by masking and shifting it down. -+ */ -+#define FIELD_GET(_mask, _reg) \ -+ ({ \ -+ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ -+ }) -+ -+static inline unsigned long align(unsigned long val, unsigned long align) -+{ -+ return (val + align - 1) & ~(align - 1); -+} -+ -+static inline unsigned long align_down(unsigned long val, unsigned long _align) -+{ -+ return align(val - (_align - 1), _align); -+} -+ -+static inline uint64_t roundup_pow_of_two(uint64_t n) -+{ -+ return n == 1 ? 1 : 1ULL << ilog64(n - 1); -+} -+ -+static inline unsigned long DIV_ROUND_UP(unsigned long n, unsigned long d) -+{ -+ return (n + d - 1) / d; -+} -+ -+int set_fd_nonblock(int fd, bool nonblock); -+ -+int open_cdev(const char *devname_hint, dev_t cdev); -+ -+unsigned int get_random(void); -+#endif --- -2.29.2 - diff --git a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0002-configure.ac-Detect-rdma-core-v36-and-v37-too.patch b/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0002-configure.ac-Detect-rdma-core-v36-and-v37-too.patch deleted file mode 100644 index b7056f53..00000000 --- a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/0002-configure.ac-Detect-rdma-core-v36-and-v37-too.patch +++ /dev/null @@ -1,118 +0,0 @@ -From ffd1f85f70551c897e6e62b89acf8b170c1c82ea Mon Sep 17 00:00:00 2001 -From: "M. Vefa Bicakci" -Date: Thu, 31 Mar 2022 16:14:22 -0400 -Subject: [PATCH] configure.ac: Detect rdma-core v36 and v37 too - -This commit makes the configure.ac script detect rdma-core v36 and v37 -as well. Of these, we are only interested in v37, because Mellanox's -OpenFabrics Enterprise Distribution is based on rdma-core v37. - -Signed-off-by: M. Vefa Bicakci ---- - configure.ac | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 75 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 9e4e980886d4..3ece437e664a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -68,6 +68,10 @@ m4_define([rcore_version],[m4_esyscmd(rc=$(grep -o \ - _ibv_device_ops verbsincpath/include/infiniband/verbs.h | \ - tail -1); \ - if test ! -z "$rc"; then \ -+ rcverv37=$(grep "IBV_WC_DRIVER3" \ -+ verbsincpath/include/infiniband/verbs.h|tail -1); \ -+ rcverv36=$(grep "ibv_query_qp_data_in_order" \ -+ verbsincpath/include/infiniband/verbs.h|tail -1); \ - rcverv35=$(grep "ibv_is_fork_initialized" \ - verbsincpath/include/infiniband/verbs.h|tail -1); \ - rcverv34=$(grep "ibv_reg_dmabuf_mr" \ -@@ -90,7 +94,11 @@ m4_define([rcore_version],[m4_esyscmd(rc=$(grep -o \ - verbsincpath/include/infiniband/verbs.h|tail -1); \ - rcverv17=$(grep -o ibv_alloc_td \ - verbsincpath/include/infiniband/verbs.h|tail -1); \ -- if test ! -z "$rcverv35"; then \ -+ if test ! -z "$rcverv37"; then \ -+ echo -n "v37"; \ -+ elif test ! -z "$rcverv36"; then \ -+ echo -n "v36"; \ -+ elif test ! -z "$rcverv35"; then \ - echo -n "v35"; \ - elif test ! -z "$rcverv34"; then \ - echo -n "v34"; \ -@@ -175,6 +183,72 @@ if test "$rc" != ""; then - AC_DEFINE([HAVE_IBV_CMD_MODIFY_QP_EX],[1],[ibv_cmd_modify_qp_ex supported]) - RDMA_CORE_HEADERS=`echo -n __include_path__` - case "$(echo -n rcore_version)" in -+ v37) -+ AC_MSG_RESULT(yes using v37) -+ AC_DEFINE([IBV_WC_DRIVER3_IN_IBV_WC_OPCODE],[1], -+ [Rdma-Core Package has IBV_WC_DRIVER3 in ibv_wc_opcode enum]) -+ AC_DEFINE([IBV_WC_DRIVER2_IN_IBV_WC_OPCODE],[1], -+ [Rdma-Core Package has IBV_WC_DRIVER2 in ibv_wc_opcode enum]) -+ AC_DEFINE([IBV_QUERY_QP_DATA_IN_ORDER_IN_CONTEXT_OPS],[1], -+ [Rdma-Core Package has query_qp_data_in_order in verbs_context_ops]) -+ AC_DEFINE([VERBS_ONLY_QUERY_DEVICE_EX_DEFINED],[1], -+ [Rdma-Core Package has only query_device_ex]) -+ AC_DEFINE([IBV_CMD_MODIFY_QP_EX_HAS_7_ARG],[1], -+ [Rdma-Core Package ibv_cmd_modify_qp_ex has 7 arguments]) -+ AC_DEFINE([IBV_FREE_CONTEXT_IN_CONTEXT_OPS],[1], -+ [Rdma-Core Package has free context in ibv_context_ops]) -+ AC_DEFINE([REG_MR_VERB_HAS_5_ARG],[1], -+ [Rdma-Core Package reg_mr has 5 argument]) -+ AC_DEFINE([IBV_CMD_ALLOC_MW_HAS_1_ARG],[1], -+ [Rdma-Core Package ibv_cmd_alloc_mw has single argument]) -+ AC_DEFINE([PROVIDER_DRIVER_HAS_2_ARGS],[1], -+ [Rdma-Core Package PROVIDER_DRIVER macro has 2 arguments]) -+ AC_DEFINE([ALLOC_CONTEXT_HAS_PRIVATE_DATA],[1], -+ [Rdma-Core Package alloc_context has private data]) -+ AC_DEFINE([VERBS_MR_DEFINED],[1], -+ [Rdma-Core Package has verbs_mr defined]) -+ AC_DEFINE([VERBS_INIT_AND_ALLOC_CONTEXT_HAS_5_ARG],[1], -+ [Rdma-Core Package has 5 Arg for verbs_init_and_alloc_context macro]) -+ AC_DEFINE([RCP_HAS_PROVIDER_DRIVER],[1], -+ [Rdma-Core Package has PROVIDER_DRIVER macro]) -+ AC_DEFINE([RCP_USE_IB_UVERBS],[1], -+ [Rdma-Core Package uses IB user verbs API]) -+ AC_DEFINE([RCP_USE_ALLOC_CONTEXT],[1], -+ [Rdma-Core Package uses alloc_context instead of init_context]) -+ rc=`grep -o ibv_read_sysfs_file src/rc-compat/v37/driver.h|tail -1` -+ ;; -+ v36) -+ AC_MSG_RESULT(yes using v36) -+ AC_DEFINE([IBV_WC_DRIVER2_IN_IBV_WC_OPCODE],[1], -+ [Rdma-Core Package has IBV_WC_DRIVER2 in ibv_wc_opcode enum]) -+ AC_DEFINE([IBV_QUERY_QP_DATA_IN_ORDER_IN_CONTEXT_OPS],[1], -+ [Rdma-Core Package has query_qp_data_in_order in verbs_context_ops]) -+ AC_DEFINE([VERBS_ONLY_QUERY_DEVICE_EX_DEFINED],[1], -+ [Rdma-Core Package has only query_device_ex]) -+ AC_DEFINE([IBV_CMD_MODIFY_QP_EX_HAS_7_ARG],[1], -+ [Rdma-Core Package ibv_cmd_modify_qp_ex has 7 arguments]) -+ AC_DEFINE([IBV_FREE_CONTEXT_IN_CONTEXT_OPS],[1], -+ [Rdma-Core Package has free context in ibv_context_ops]) -+ AC_DEFINE([REG_MR_VERB_HAS_5_ARG],[1], -+ [Rdma-Core Package reg_mr has 5 argument]) -+ AC_DEFINE([IBV_CMD_ALLOC_MW_HAS_1_ARG],[1], -+ [Rdma-Core Package ibv_cmd_alloc_mw has single argument]) -+ AC_DEFINE([PROVIDER_DRIVER_HAS_2_ARGS],[1], -+ [Rdma-Core Package PROVIDER_DRIVER macro has 2 arguments]) -+ AC_DEFINE([ALLOC_CONTEXT_HAS_PRIVATE_DATA],[1], -+ [Rdma-Core Package alloc_context has private data]) -+ AC_DEFINE([VERBS_MR_DEFINED],[1], -+ [Rdma-Core Package has verbs_mr defined]) -+ AC_DEFINE([VERBS_INIT_AND_ALLOC_CONTEXT_HAS_5_ARG],[1], -+ [Rdma-Core Package has 5 Arg for verbs_init_and_alloc_context macro]) -+ AC_DEFINE([RCP_HAS_PROVIDER_DRIVER],[1], -+ [Rdma-Core Package has PROVIDER_DRIVER macro]) -+ AC_DEFINE([RCP_USE_IB_UVERBS],[1], -+ [Rdma-Core Package uses IB user verbs API]) -+ AC_DEFINE([RCP_USE_ALLOC_CONTEXT],[1], -+ [Rdma-Core Package uses alloc_context instead of init_context]) -+ rc=`grep -o ibv_read_sysfs_file src/rc-compat/v36/driver.h|tail -1` -+ ;; - v35) - AC_MSG_RESULT(yes using v35) - AC_DEFINE([VERBS_ONLY_QUERY_DEVICE_EX_DEFINED],[1], --- -2.29.2 - diff --git a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/series b/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/series index dcb9a3bf..e69de29b 100644 --- a/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/series +++ b/userspace/broadcom/libbnxt_re/debian/deb_folder/patches/series @@ -1,2 +0,0 @@ -0001-rc-compat-Add-headers-from-v37.3.patch -0002-configure.ac-Detect-rdma-core-v36-and-v37-too.patch diff --git a/userspace/broadcom/libbnxt_re/debian/dl_hook b/userspace/broadcom/libbnxt_re/debian/dl_hook index d9919f88..779ede90 100755 --- a/userspace/broadcom/libbnxt_re/debian/dl_hook +++ b/userspace/broadcom/libbnxt_re/debian/dl_hook @@ -24,8 +24,8 @@ # building. # Tools needed: mkdir, rm, tar -DL_TARBALL=bcm_220.0.83.0.tar.gz -SRC_TARBALL=Linux/Linux_RoCE/RoCE_Lib/libbnxt_re-220.0.5.0.tar.gz +DL_TARBALL=bcm_227.1.111.0b.tar.gz +SRC_TARBALL=Linux/Linux_RoCE/RoCE_Lib/libbnxt_re-227.0.130.0.tar.gz TMPDIR="bcm_tmp" DESTDIR="${1}" diff --git a/userspace/broadcom/libbnxt_re/debian/meta_data.yaml b/userspace/broadcom/libbnxt_re/debian/meta_data.yaml index 5ba59e9e..2eedeb7c 100644 --- a/userspace/broadcom/libbnxt_re/debian/meta_data.yaml +++ b/userspace/broadcom/libbnxt_re/debian/meta_data.yaml @@ -1,14 +1,14 @@ --- -debver: 220.0.5.0 +debver: 227.0.130.0 debname: libbnxt-re dl_hook: dl_hook dl_files: - bcm_220.0.83.0.tar.gz: + bcm_227.1.111.0b.tar.gz: topdir: null url: "https://docs.broadcom.com/docs-and-downloads/\ - ethernet-network-adapters/NXE/BRCM_220.0.83.0/\ - bcm_220.0.83.0.tar.gz" - sha256sum: 85bdfc30b4bd3e184e3b57a48055c11085e3b97593f7b4a8347fa50a9d571336 + ethernet-network-adapters/NXE/BRCM_227.1.111.0/\ + bcm_227.1.111.0b.tar.gz" + sha256sum: 184977c9043b64358d65c9412063377ed5fc4d9efb225c31ce5e11f1b16b5418 revision: dist: $STX_DIST GITREVCOUNT: