From patchwork Wed May 27 16:14:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ophir Munk X-Patchwork-Id: 70659 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0B6A3A0093; Wed, 27 May 2020 18:14:54 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AA3311D654; Wed, 27 May 2020 18:14:46 +0200 (CEST) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70075.outbound.protection.outlook.com [40.107.7.75]) by dpdk.org (Postfix) with ESMTP id 56C371D545 for ; Wed, 27 May 2020 18:14:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BQFEt6tcZXlCLp5M+yYKFVGqY675dZtONggwPyuZG7Tawf/I7a2eBp6FMsIFmG9uDLIJEZr4/8P9m06Dc95mTaiQ4PsvPCjoN6sv2NH6l3g8PQ8O52p1ssuMe2D9Jf2KTLi46R3sLWxErF+23rf2wVlOQdu7j9osNS6UruQUYLb3eSIo9vjBVcxY04q4r8Lx5Ek1TuB26yrRqal2Xa/eU3IFvQE+VJtHmFANxZw9quR72wypXy0IX6Ms/0AXa9YX+MbvinAeZZdLPYYo73K8jauaGc76/bcaDwwq42YKZVVpaIzl5cGjCXZr9simrpKCwXdUNwdSzj3p45pOkE6uQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=N+vhtqhEp/fp3NLXNJTqBF+dPkEecWB3dg8N/XMw1HU=; b=BNlQJFkIlHHto14jX2/G8a1kgoCr5O3ntM+5bLLRTSdcV8B3bzFEQF+GVLMUnI2cf0FQiniS06toL6/3313kJcr1o7JZvvOf77CLznAGdF4Q5JldP7+eSTgHCvWliVtiYh6tyw+mXi2/0C0Fcykw4wDFq2seGDt4I9Vf6aEn1HPH5Cf8JnM/Pzg5wLdT5nHv5j4kW7nRjd/xXphlRRms1QM5/RvIA+KDxpScP+F+mSDEOEKZ74cJrMLTITMCNiqUKLh7peOo4+MUtFqpIdBxrFAx0Cv+BkPS9GwUCb0RbaBtCwc2SoYL8nCJu8o2DNOz29DKcLAC5psjrvhcUk+yPw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=N+vhtqhEp/fp3NLXNJTqBF+dPkEecWB3dg8N/XMw1HU=; b=S1hyryhNLbyU0RnwrG1UTVFcCJjZXVZ+xLvWyY/5nvUjik0XaxVwncp9bndYPYfOp/YuQxXzlJAiIJ9wMDRzefZ2ltaO67o0V9jt1WGeMbi8+4VWCjhEkaJQQknW2bUdRkV4SeL0TO4/RNGvUMT830sCMBTHscRqPCUxZrpt18c= Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=mellanox.com; Received: from AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) by AM0PR05MB4497.eurprd05.prod.outlook.com (2603:10a6:208:67::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.24; Wed, 27 May 2020 16:14:40 +0000 Received: from AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a]) by AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a%3]) with mapi id 15.20.3021.029; Wed, 27 May 2020 16:14:40 +0000 From: Ophir Munk To: dev@dpdk.org, Matan Azrad Cc: Ophir Munk Date: Wed, 27 May 2020 16:14:23 +0000 Message-Id: <20200527161425.22944-1-ophirmu@mellanox.com> X-Mailer: git-send-email 2.8.4 X-ClientProxiedBy: AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) To AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from mellanox.com (37.142.13.130) by AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.18 via Frontend Transport; Wed, 27 May 2020 16:14:39 +0000 X-Mailer: git-send-email 2.8.4 X-Originating-IP: [37.142.13.130] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 16b86879-f600-4d1f-f464-08d802590eaf X-MS-TrafficTypeDiagnostic: AM0PR05MB4497: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2399; X-Forefront-PRVS: 04163EF38A X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oXhlYZ7ZgsEkQPpaPyMOZdAPd56wBr9iMmJMJcSce46pcy8Z2MG/uwLOTihVlsFJIj1PV87V8gB5woDmocI41GhVK6D9JdWnEl4wLD88r4DVdst350ci5jhWEjuw9r14K6GmlDktwJA2L1aHvr4WVgeH38JXW9ilqIT4P7+3JO0g9yH1mtv5ZbXHD385Zcr/AQLg3xZnj1O9VXgiljV+ohGEiUxnMrUvi1+qI+wzFttLZ5CJ1Fxkz9gmnqgEDy2HTrtbiN+r+jLWFfdH3YeoxQ7410PAbpnI8ZWsXBeOAiD9Rb1/+S8pEzGKkDh/pFla X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM0PR05MB4209.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(39860400002)(376002)(346002)(396003)(366004)(136003)(2906002)(6636002)(7696005)(8886007)(1076003)(26005)(8676002)(5660300002)(37006003)(52116002)(36756003)(186003)(16526019)(30864003)(6666004)(83380400001)(8936002)(316002)(478600001)(66946007)(66556008)(86362001)(2616005)(956004)(66476007)(6862004)(107886003)(4326008)(55016002)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: OuP+DolcaCuDvqAUlbzqjpVDtzHQUmSrzXaIx+VmM5ubaNs5sZ1Vt8P4k/QS7Ut/bMFhBUcsi6S9roU+ofAlmyaAj16o+fUIpTvqOKoSJBRNqGlKW/2UA7dtBDrv2qccG5ktmGY+OhfS/Z/cWUFN/JtkNvnatfC/XDvTHu7q3qepPg5rdvUrJARdEPOVemS1X7Xe+yoOWF8Lu/5svOkl+0sMhXZ//j1zAtPHa/aV7Ew7NM9gfdAQiJRJAwSgWHUZYovAn539S4/tT1n3GeTTNieKvVUZVV5I1F5ZUj7eEaNJoEn2iQ5zKmkvPwTu/O49XgObDCaOifHrR+TytOaCNEPLP+4HUnef7HZsIb91XAM+weYxXCBEk4bJ/rfAXRtrGkZhaG2XDoRHtnSEYFkajMQizXC35wpL0iFix7TpJjCwpS/CO5xxCl20Riyhd7h1ILXSI07wh82FKUdWzRrVyMW6AylxCynJHmI9dlvF7WU= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 16b86879-f600-4d1f-f464-08d802590eaf X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 May 2020 16:14:39.9239 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: n6wHuWtrToS0Cj/njRjOoGE4pb7ol0uQMkULWj8ZMuNgQKDEA36G2TAAx5scSquZ6YP+skG7EyDS30ibVNTFFw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4497 Subject: [dpdk-dev] [PATCH v1 1/3] common/mlx5: move glue files under Linux directory X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The glue file mlx5_glue.c is based on Linux specifics APIs. Move it (including file mlx5_glue.h) to common/mlx5/linux directory. Signed-off-by: Ophir Munk --- drivers/common/mlx5/Makefile | 12 +- drivers/common/mlx5/linux/meson.build | 199 +++++ drivers/common/mlx5/linux/mlx5_glue.c | 1294 +++++++++++++++++++++++++++++++++ drivers/common/mlx5/linux/mlx5_glue.h | 309 ++++++++ drivers/common/mlx5/meson.build | 200 +---- drivers/common/mlx5/mlx5_glue.c | 1294 --------------------------------- drivers/common/mlx5/mlx5_glue.h | 309 -------- drivers/net/mlx5/Makefile | 1 + drivers/vdpa/mlx5/Makefile | 1 + 9 files changed, 1817 insertions(+), 1802 deletions(-) create mode 100644 drivers/common/mlx5/linux/meson.build create mode 100644 drivers/common/mlx5/linux/mlx5_glue.c create mode 100644 drivers/common/mlx5/linux/mlx5_glue.h delete mode 100644 drivers/common/mlx5/mlx5_glue.c delete mode 100644 drivers/common/mlx5/mlx5_glue.h diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 0d8cc1b..19b1466 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -12,7 +12,7 @@ LIB_GLUE_VERSION = 20.02.0 # Sources. ifeq ($(findstring y,$(CONFIG_RTE_LIBRTE_MLX5_PMD)$(CONFIG_RTE_LIBRTE_MLX5_VDPA_PMD)),y) ifneq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) -SRCS-y += mlx5_glue.c +SRCS-y += linux/mlx5_glue.c endif SRCS-y += mlx5_devx_cmds.c SRCS-y += mlx5_common.c @@ -29,6 +29,8 @@ CFLAGS += -O3 CFLAGS += -std=c11 -Wall -Wextra CFLAGS += -g CFLAGS += -I. +CFLAGS += -I$(SRCDIR) +CFLAGS += -I$(SRCDIR)/linux CFLAGS += -D_BSD_SOURCE CFLAGS += -D_DEFAULT_SOURCE CFLAGS += -D_XOPEN_SOURCE=600 @@ -37,7 +39,7 @@ CFLAGS += -Wno-strict-prototypes ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' -CFLAGS_mlx5_glue.o += -fPIC +CFLAGS_linux/mlx5_glue.o += -fPIC LDLIBS += -ldl else ifeq ($(CONFIG_RTE_IBVERBS_LINK_STATIC),y) LDLIBS += $(shell $(RTE_SDK)/buildtools/options-ibverbs-static.sh) @@ -346,17 +348,17 @@ GLUE_LDFLAGS := $(call linkerprefix,$(LDFLAGS)) else GLUE_LDFLAGS := $(LDFLAGS) endif -$(LIB_GLUE): mlx5_glue.o +$(LIB_GLUE): linux/mlx5_glue.o $Q $(LD) $(GLUE_LDFLAGS) $(EXTRA_LDFLAGS) \ -Wl,-h,$(LIB_GLUE) \ -shared -o $@ $< -libverbs -lmlx5 -mlx5_glue.o: mlx5_autoconf.h +linux/mlx5_glue.o: mlx5_autoconf.h endif clean_mlx5: FORCE $Q rm -f -- mlx5_autoconf.h mlx5_autoconf.h.new - $Q rm -f -- mlx5_glue.o $(LIB_GLUE_BASE)* + $Q rm -f -- linux/mlx5_glue.o $(LIB_GLUE_BASE)* clean: clean_mlx5 diff --git a/drivers/common/mlx5/linux/meson.build b/drivers/common/mlx5/linux/meson.build new file mode 100644 index 0000000..a123fd6 --- /dev/null +++ b/drivers/common/mlx5/linux/meson.build @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2020 Mellanox Technologies, Ltd + +includes += include_directories('.') + +static_ibverbs = (get_option('ibverbs_link') == 'static') +dlopen_ibverbs = (get_option('ibverbs_link') == 'dlopen') +LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so' +LIB_GLUE_VERSION = '20.02.0' +LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION +if dlopen_ibverbs + dpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1) + cflags += [ + '-DMLX5_GLUE="@0@"'.format(LIB_GLUE), + '-DMLX5_GLUE_VERSION="@0@"'.format(LIB_GLUE_VERSION), + ] +endif + +libnames = [ 'mlx5', 'ibverbs' ] +libs = [] +foreach libname:libnames + lib = dependency('lib' + libname, static:static_ibverbs, required:false) + if not lib.found() and not static_ibverbs + lib = cc.find_library(libname, required:false) + endif + if lib.found() + libs += lib + if not static_ibverbs and not dlopen_ibverbs + ext_deps += lib + endif + else + build = false + reason = 'missing dependency, "' + libname + '"' + subdir_done() + endif +endforeach +if static_ibverbs or dlopen_ibverbs + # Build without adding shared libs to Requires.private + ibv_cflags = run_command(pkgconf, '--cflags', 'libibverbs').stdout() + ext_deps += declare_dependency(compile_args: ibv_cflags.split()) +endif +if static_ibverbs + # Add static deps ldflags to internal apps and Libs.private + ibv_ldflags = run_command(ldflags_ibverbs_static, check:true).stdout() + ext_deps += declare_dependency(link_args:ibv_ldflags.split()) +endif + +if not dlopen_ibverbs + sources += files('mlx5_glue.c') +endif + +# To maintain the compatibility with the make build system +# mlx5_autoconf.h file is still generated. +# input array for meson member search: +# [ "MACRO to define if found", "header for the search", +# "symbol to search", "struct member to search" ] +has_member_args = [ + [ 'HAVE_IBV_MLX5_MOD_SWP', 'infiniband/mlx5dv.h', + 'struct mlx5dv_sw_parsing_caps', 'sw_parsing_offloads' ], + [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V42', 'infiniband/verbs.h', + 'struct ibv_counter_set_init_attr', 'counter_set_id' ], + [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V45', 'infiniband/verbs.h', + 'struct ibv_counters_init_attr', 'comp_mask' ], +] +# input array for meson symbol search: +# [ "MACRO to define if found", "header for the search", +# "symbol to search" ] +has_sym_args = [ + [ 'HAVE_IBV_RELAXED_ORDERING', 'infiniband/verbs.h', + 'IBV_ACCESS_RELAXED_ORDERING ' ], + [ 'HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT', 'infiniband/mlx5dv.h', + 'MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX' ], + [ 'HAVE_IBV_DEVICE_TUNNEL_SUPPORT', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS' ], + [ 'HAVE_IBV_MLX5_MOD_MPW', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED' ], + [ 'HAVE_IBV_MLX5_MOD_CQE_128B_COMP', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP' ], + [ 'HAVE_IBV_MLX5_MOD_CQE_128B_PAD', 'infiniband/mlx5dv.h', + 'MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD' ], + [ 'HAVE_IBV_FLOW_DV_SUPPORT', 'infiniband/mlx5dv.h', + 'mlx5dv_create_flow_action_packet_reformat' ], + [ 'HAVE_IBV_DEVICE_MPLS_SUPPORT', 'infiniband/verbs.h', + 'IBV_FLOW_SPEC_MPLS' ], + [ 'HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING', 'infiniband/verbs.h', + 'IBV_WQ_FLAGS_PCI_WRITE_END_PADDING' ], + [ 'HAVE_IBV_WQ_FLAG_RX_END_PADDING', 'infiniband/verbs.h', + 'IBV_WQ_FLAG_RX_END_PADDING' ], + [ 'HAVE_MLX5DV_DR_DEVX_PORT', 'infiniband/mlx5dv.h', + 'mlx5dv_query_devx_port' ], + [ 'HAVE_IBV_DEVX_OBJ', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_obj_create' ], + [ 'HAVE_IBV_FLOW_DEVX_COUNTERS', 'infiniband/mlx5dv.h', + 'MLX5DV_FLOW_ACTION_COUNTERS_DEVX' ], + [ 'HAVE_IBV_DEVX_ASYNC', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_obj_query_async' ], + [ 'HAVE_IBV_DEVX_QP', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_qp_query' ], + [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_dest_devx_tir' ], + [ 'HAVE_IBV_DEVX_EVENT', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_get_event' ], + [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_flow_meter' ], + [ 'HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD', 'infiniband/mlx5dv.h', + 'MLX5_MMAP_GET_NC_PAGES_CMD' ], + [ 'HAVE_MLX5DV_DR', 'infiniband/mlx5dv.h', + 'MLX5DV_DR_DOMAIN_TYPE_NIC_RX' ], + [ 'HAVE_MLX5DV_DR_ESWITCH', 'infiniband/mlx5dv.h', + 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], + [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_push_vlan' ], + [ 'HAVE_IBV_VAR', 'infiniband/mlx5dv.h', 'mlx5dv_alloc_var' ], + [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseKR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseCR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseSR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseSR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseLR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseLR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseKR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseKR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseCR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseCR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseSR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseSR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseLR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseLR4_Full' ], + [ 'HAVE_ETHTOOL_LINK_MODE_25G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_25000baseCR_Full_BIT' ], + [ 'HAVE_ETHTOOL_LINK_MODE_50G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT' ], + [ 'HAVE_ETHTOOL_LINK_MODE_100G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT' ], + [ 'HAVE_IFLA_NUM_VF', 'linux/if_link.h', + 'IFLA_NUM_VF' ], + [ 'HAVE_IFLA_EXT_MASK', 'linux/if_link.h', + 'IFLA_EXT_MASK' ], + [ 'HAVE_IFLA_PHYS_SWITCH_ID', 'linux/if_link.h', + 'IFLA_PHYS_SWITCH_ID' ], + [ 'HAVE_IFLA_PHYS_PORT_NAME', 'linux/if_link.h', + 'IFLA_PHYS_PORT_NAME' ], + [ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h', + 'RDMA_NL_NLDEV' ], + [ 'HAVE_RDMA_NLDEV_CMD_GET', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_CMD_GET' ], + [ 'HAVE_RDMA_NLDEV_CMD_PORT_GET', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_CMD_PORT_GET' ], + [ 'HAVE_RDMA_NLDEV_ATTR_DEV_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_DEV_INDEX' ], + [ 'HAVE_RDMA_NLDEV_ATTR_DEV_NAME', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_DEV_NAME' ], + [ 'HAVE_RDMA_NLDEV_ATTR_PORT_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_PORT_INDEX' ], + [ 'HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_NDEV_INDEX' ], + [ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h', + 'mlx5dv_dump_dr_domain'], + [ 'HAVE_DEVLINK', 'linux/devlink.h', 'DEVLINK_GENL_NAME' ], +] +config = configuration_data() +foreach arg:has_sym_args + config.set(arg[0], cc.has_header_symbol(arg[1], arg[2], + dependencies: libs)) +endforeach +foreach arg:has_member_args + file_prefix = '#include <' + arg[1] + '>' + config.set(arg[0], cc.has_member(arg[2], arg[3], + prefix : file_prefix, dependencies: libs)) +endforeach +configure_file(output : 'mlx5_autoconf.h', configuration : config) + +# Build Glue Library +if dlopen_ibverbs + dlopen_name = 'mlx5_glue' + dlopen_lib_name = 'rte_pmd_@0@'.format(dlopen_name) + dlopen_so_version = LIB_GLUE_VERSION + dlopen_sources = files('mlx5_glue.c') + dlopen_install_dir = [ eal_pmd_path + '-glue' ] + dlopen_includes = [global_inc] + dlopen_includes += include_directories( + '../../../../lib/librte_eal/include/generic', + ) + shared_lib = shared_library( + dlopen_lib_name, + dlopen_sources, + include_directories: dlopen_includes, + c_args: cflags, + dependencies: libs, + link_args: [ + '-Wl,-export-dynamic', + '-Wl,-h,@0@'.format(LIB_GLUE), + ], + soversion: dlopen_so_version, + install: true, + install_dir: dlopen_install_dir, + ) +endif diff --git a/drivers/common/mlx5/linux/mlx5_glue.c b/drivers/common/mlx5/linux/mlx5_glue.c new file mode 100644 index 0000000..f270f67 --- /dev/null +++ b/drivers/common/mlx5/linux/mlx5_glue.c @@ -0,0 +1,1294 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include +#include +/* + * Not needed by this file; included to work around the lack of off_t + * definition for mlx5dv.h with unpatched rdma-core versions. + */ +#include + +#include "mlx5_glue.h" + +static int +mlx5_glue_fork_init(void) +{ + return ibv_fork_init(); +} + +static struct ibv_pd * +mlx5_glue_alloc_pd(struct ibv_context *context) +{ + return ibv_alloc_pd(context); +} + +static int +mlx5_glue_dealloc_pd(struct ibv_pd *pd) +{ + return ibv_dealloc_pd(pd); +} + +static struct ibv_device ** +mlx5_glue_get_device_list(int *num_devices) +{ + return ibv_get_device_list(num_devices); +} + +static void +mlx5_glue_free_device_list(struct ibv_device **list) +{ + ibv_free_device_list(list); +} + +static struct ibv_context * +mlx5_glue_open_device(struct ibv_device *device) +{ + return ibv_open_device(device); +} + +static int +mlx5_glue_close_device(struct ibv_context *context) +{ + return ibv_close_device(context); +} + +static int +mlx5_glue_query_device(struct ibv_context *context, + struct ibv_device_attr *device_attr) +{ + return ibv_query_device(context, device_attr); +} + +static int +mlx5_glue_query_device_ex(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr) +{ + return ibv_query_device_ex(context, input, attr); +} + +static int +mlx5_glue_query_rt_values_ex(struct ibv_context *context, + struct ibv_values_ex *values) +{ + return ibv_query_rt_values_ex(context, values); +} + +static int +mlx5_glue_query_port(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr) +{ + return ibv_query_port(context, port_num, port_attr); +} + +static struct ibv_comp_channel * +mlx5_glue_create_comp_channel(struct ibv_context *context) +{ + return ibv_create_comp_channel(context); +} + +static int +mlx5_glue_destroy_comp_channel(struct ibv_comp_channel *channel) +{ + return ibv_destroy_comp_channel(channel); +} + +static struct ibv_cq * +mlx5_glue_create_cq(struct ibv_context *context, int cqe, void *cq_context, + struct ibv_comp_channel *channel, int comp_vector) +{ + return ibv_create_cq(context, cqe, cq_context, channel, comp_vector); +} + +static int +mlx5_glue_destroy_cq(struct ibv_cq *cq) +{ + return ibv_destroy_cq(cq); +} + +static int +mlx5_glue_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, + void **cq_context) +{ + return ibv_get_cq_event(channel, cq, cq_context); +} + +static void +mlx5_glue_ack_cq_events(struct ibv_cq *cq, unsigned int nevents) +{ + ibv_ack_cq_events(cq, nevents); +} + +static struct ibv_rwq_ind_table * +mlx5_glue_create_rwq_ind_table(struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr) +{ + return ibv_create_rwq_ind_table(context, init_attr); +} + +static int +mlx5_glue_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) +{ + return ibv_destroy_rwq_ind_table(rwq_ind_table); +} + +static struct ibv_wq * +mlx5_glue_create_wq(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr) +{ + return ibv_create_wq(context, wq_init_attr); +} + +static int +mlx5_glue_destroy_wq(struct ibv_wq *wq) +{ + return ibv_destroy_wq(wq); +} +static int +mlx5_glue_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr) +{ + return ibv_modify_wq(wq, wq_attr); +} + +static struct ibv_flow * +mlx5_glue_create_flow(struct ibv_qp *qp, struct ibv_flow_attr *flow) +{ + return ibv_create_flow(qp, flow); +} + +static int +mlx5_glue_destroy_flow(struct ibv_flow *flow_id) +{ + return ibv_destroy_flow(flow_id); +} + +static int +mlx5_glue_destroy_flow_action(void *action) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_destroy(action); +#else + struct mlx5dv_flow_action_attr *attr = action; + int res = 0; + switch (attr->type) { + case MLX5DV_FLOW_ACTION_TAG: + break; + default: + res = ibv_destroy_flow_action(attr->action); + break; + } + free(action); + return res; +#endif +#else + (void)action; + return ENOTSUP; +#endif +} + +static struct ibv_qp * +mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) +{ + return ibv_create_qp(pd, qp_init_attr); +} + +static struct ibv_qp * +mlx5_glue_create_qp_ex(struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex) +{ + return ibv_create_qp_ex(context, qp_init_attr_ex); +} + +static int +mlx5_glue_destroy_qp(struct ibv_qp *qp) +{ + return ibv_destroy_qp(qp); +} + +static int +mlx5_glue_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) +{ + return ibv_modify_qp(qp, attr, attr_mask); +} + +static struct ibv_mr * +mlx5_glue_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access) +{ + return ibv_reg_mr(pd, addr, length, access); +} + +static struct ibv_mr * +mlx5_glue_alloc_null_mr(struct ibv_pd *pd) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return ibv_alloc_null_mr(pd); +#else + (void)pd; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dereg_mr(struct ibv_mr *mr) +{ + return ibv_dereg_mr(mr); +} + +static struct ibv_counter_set * +mlx5_glue_create_counter_set(struct ibv_context *context, + struct ibv_counter_set_init_attr *init_attr) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)context; + (void)init_attr; + return NULL; +#else + return ibv_create_counter_set(context, init_attr); +#endif +} + +static int +mlx5_glue_destroy_counter_set(struct ibv_counter_set *cs) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)cs; + return ENOTSUP; +#else + return ibv_destroy_counter_set(cs); +#endif +} + +static int +mlx5_glue_describe_counter_set(struct ibv_context *context, + uint16_t counter_set_id, + struct ibv_counter_set_description *cs_desc) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)context; + (void)counter_set_id; + (void)cs_desc; + return ENOTSUP; +#else + return ibv_describe_counter_set(context, counter_set_id, cs_desc); +#endif +} + +static int +mlx5_glue_query_counter_set(struct ibv_query_counter_set_attr *query_attr, + struct ibv_counter_set_data *cs_data) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)query_attr; + (void)cs_data; + return ENOTSUP; +#else + return ibv_query_counter_set(query_attr, cs_data); +#endif +} + +static struct ibv_counters * +mlx5_glue_create_counters(struct ibv_context *context, + struct ibv_counters_init_attr *init_attr) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)context; + (void)init_attr; + errno = ENOTSUP; + return NULL; +#else + return ibv_create_counters(context, init_attr); +#endif +} + +static int +mlx5_glue_destroy_counters(struct ibv_counters *counters) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + return ENOTSUP; +#else + return ibv_destroy_counters(counters); +#endif +} + +static int +mlx5_glue_attach_counters(struct ibv_counters *counters, + struct ibv_counter_attach_attr *attr, + struct ibv_flow *flow) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + (void)attr; + (void)flow; + return ENOTSUP; +#else + return ibv_attach_counters_point_flow(counters, attr, flow); +#endif +} + +static int +mlx5_glue_query_counters(struct ibv_counters *counters, + uint64_t *counters_value, + uint32_t ncounters, + uint32_t flags) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + (void)counters_value; + (void)ncounters; + (void)flags; + return ENOTSUP; +#else + return ibv_read_counters(counters, counters_value, ncounters, flags); +#endif +} + +static void +mlx5_glue_ack_async_event(struct ibv_async_event *event) +{ + ibv_ack_async_event(event); +} + +static int +mlx5_glue_get_async_event(struct ibv_context *context, + struct ibv_async_event *event) +{ + return ibv_get_async_event(context, event); +} + +static const char * +mlx5_glue_port_state_str(enum ibv_port_state port_state) +{ + return ibv_port_state_str(port_state); +} + +static struct ibv_cq * +mlx5_glue_cq_ex_to_cq(struct ibv_cq_ex *cq) +{ + return ibv_cq_ex_to_cq(cq); +} + +static void * +mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_dest_table(tbl); +#else + (void)tbl; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_dest_port(void *domain, uint32_t port) +{ +#ifdef HAVE_MLX5DV_DR_DEVX_PORT + return mlx5dv_dr_action_create_dest_ib_port(domain, port); +#else +#ifdef HAVE_MLX5DV_DR_ESWITCH + return mlx5dv_dr_action_create_dest_vport(domain, port); +#else + (void)domain; + (void)port; + errno = ENOTSUP; + return NULL; +#endif +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_drop(void) +{ +#ifdef HAVE_MLX5DV_DR_ESWITCH + return mlx5dv_dr_action_create_drop(); +#else + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_push_vlan(struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_push_vlan(domain, vlan_tag); +#else + (void)domain; + (void)vlan_tag; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_pop_vlan(void) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_pop_vlan(); +#else + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_table_create(domain, level); +#else + (void)domain; + (void)level; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dr_destroy_flow_tbl(void *tbl) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_table_destroy(tbl); +#else + (void)tbl; + errno = ENOTSUP; + return errno; +#endif +} + +static void * +mlx5_glue_dr_create_domain(struct ibv_context *ctx, + enum mlx5dv_dr_domain_type domain) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_domain_create(ctx, domain); +#else + (void)ctx; + (void)domain; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dr_destroy_domain(void *domain) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_domain_destroy(domain); +#else + (void)domain; + errno = ENOTSUP; + return errno; +#endif +} + +static struct ibv_cq_ex * +mlx5_glue_dv_create_cq(struct ibv_context *context, + struct ibv_cq_init_attr_ex *cq_attr, + struct mlx5dv_cq_init_attr *mlx5_cq_attr) +{ + return mlx5dv_create_cq(context, cq_attr, mlx5_cq_attr); +} + +static struct ibv_wq * +mlx5_glue_dv_create_wq(struct ibv_context *context, + struct ibv_wq_init_attr *wq_attr, + struct mlx5dv_wq_init_attr *mlx5_wq_attr) +{ +#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT + (void)context; + (void)wq_attr; + (void)mlx5_wq_attr; + errno = ENOTSUP; + return NULL; +#else + return mlx5dv_create_wq(context, wq_attr, mlx5_wq_attr); +#endif +} + +static int +mlx5_glue_dv_query_device(struct ibv_context *ctx, + struct mlx5dv_context *attrs_out) +{ + return mlx5dv_query_device(ctx, attrs_out); +} + +static int +mlx5_glue_dv_set_context_attr(struct ibv_context *ibv_ctx, + enum mlx5dv_set_ctx_attr_type type, void *attr) +{ + return mlx5dv_set_context_attr(ibv_ctx, type, attr); +} + +static int +mlx5_glue_dv_init_obj(struct mlx5dv_obj *obj, uint64_t obj_type) +{ + return mlx5dv_init_obj(obj, obj_type); +} + +static struct ibv_qp * +mlx5_glue_dv_create_qp(struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex, + struct mlx5dv_qp_init_attr *dv_qp_init_attr) +{ +#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT + return mlx5dv_create_qp(context, qp_init_attr_ex, dv_qp_init_attr); +#else + (void)context; + (void)qp_init_attr_ex; + (void)dv_qp_init_attr; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_matcher(struct ibv_context *context, + struct mlx5dv_flow_matcher_attr *matcher_attr, + void *tbl) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)context; + return mlx5dv_dr_matcher_create(tbl, matcher_attr->priority, + matcher_attr->match_criteria_enable, + matcher_attr->match_mask); +#else + (void)tbl; + return mlx5dv_create_flow_matcher(context, matcher_attr); +#endif +#else + (void)context; + (void)matcher_attr; + (void)tbl; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow(void *matcher, + void *match_value, + size_t num_actions, + void *actions[]) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_rule_create(matcher, match_value, num_actions, + (struct mlx5dv_dr_action **)actions); +#else + struct mlx5dv_flow_action_attr actions_attr[8]; + + if (num_actions > 8) + return NULL; + for (size_t i = 0; i < num_actions; i++) + actions_attr[i] = + *((struct mlx5dv_flow_action_attr *)(actions[i])); + return mlx5dv_create_flow(matcher, match_value, + num_actions, actions_attr); +#endif +#else + (void)matcher; + (void)match_value; + (void)num_actions; + (void)actions; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_counter(void *counter_obj, uint32_t offset) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_flow_counter(counter_obj, offset); +#else + struct mlx5dv_flow_action_attr *action; + + (void)offset; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_COUNTERS_DEVX; + action->obj = counter_obj; + return action; +#endif +#else + (void)counter_obj; + (void)offset; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_dest_ibv_qp(void *qp) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_dest_ibv_qp(qp); +#else + struct mlx5dv_flow_action_attr *action; + + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_DEST_IBV_QP; + action->obj = qp; + return action; +#endif +#else + (void)qp; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_dest_devx_tir(void *tir) +{ +#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR + return mlx5dv_dr_action_create_dest_devx_tir(tir); +#else + (void)tir; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_modify_header + (struct ibv_context *ctx, + enum mlx5dv_flow_table_type ft_type, + void *domain, uint64_t flags, + size_t actions_sz, + uint64_t actions[]) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)ctx; + (void)ft_type; + return mlx5dv_dr_action_create_modify_header(domain, flags, actions_sz, + (__be64 *)actions); +#else + struct mlx5dv_flow_action_attr *action; + + (void)domain; + (void)flags; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + action->action = mlx5dv_create_flow_action_modify_header + (ctx, actions_sz, actions, ft_type); + return action; +#endif +#else + (void)ctx; + (void)ft_type; + (void)domain; + (void)flags; + (void)actions_sz; + (void)actions; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_packet_reformat + (struct ibv_context *ctx, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type, + struct mlx5dv_dr_domain *domain, + uint32_t flags, size_t data_sz, void *data) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)ctx; + (void)ft_type; + return mlx5dv_dr_action_create_packet_reformat(domain, flags, + reformat_type, data_sz, + data); +#else + (void)domain; + (void)flags; + struct mlx5dv_flow_action_attr *action; + + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + action->action = mlx5dv_create_flow_action_packet_reformat + (ctx, data_sz, data, reformat_type, ft_type); + return action; +#endif +#else + (void)ctx; + (void)reformat_type; + (void)ft_type; + (void)domain; + (void)flags; + (void)data_sz; + (void)data; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_tag(uint32_t tag) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_tag(tag); +#else + struct mlx5dv_flow_action_attr *action; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_TAG; + action->tag_value = tag; + return action; +#endif +#endif + (void)tag; + errno = ENOTSUP; + return NULL; +} + +static void * +mlx5_glue_dv_create_flow_action_meter(struct mlx5dv_dr_flow_meter_attr *attr) +{ +#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) + return mlx5dv_dr_action_create_flow_meter(attr); +#else + (void)attr; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dv_modify_flow_action_meter(void *action, + struct mlx5dv_dr_flow_meter_attr *attr, + uint64_t modify_bits) +{ +#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) + return mlx5dv_dr_action_modify_flow_meter(action, attr, modify_bits); +#else + (void)action; + (void)attr; + (void)modify_bits; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_dv_destroy_flow(void *flow_id) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_rule_destroy(flow_id); +#else + return ibv_destroy_flow(flow_id); +#endif +} + +static int +mlx5_glue_dv_destroy_flow_matcher(void *matcher) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_matcher_destroy(matcher); +#else + return mlx5dv_destroy_flow_matcher(matcher); +#endif +#else + (void)matcher; + errno = ENOTSUP; + return errno; +#endif +} + +static struct ibv_context * +mlx5_glue_dv_open_device(struct ibv_device *device) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_open_device(device, + &(struct mlx5dv_context_attr){ + .flags = MLX5DV_CONTEXT_FLAGS_DEVX, + }); +#else + (void)device; + errno = ENOTSUP; + return NULL; +#endif +} + +static struct mlx5dv_devx_obj * +mlx5_glue_devx_obj_create(struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_create(ctx, in, inlen, out, outlen); +#else + (void)ctx; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_devx_obj_destroy(struct mlx5dv_devx_obj *obj) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_destroy(obj); +#else + (void)obj; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_query(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_query(obj, in, inlen, out, outlen); +#else + (void)obj; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_modify(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_modify(obj, in, inlen, out, outlen); +#else + (void)obj; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_general_cmd(struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_general_cmd(ctx, in, inlen, out, outlen); +#else + (void)ctx; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static struct mlx5dv_devx_cmd_comp * +mlx5_glue_devx_create_cmd_comp(struct ibv_context *ctx) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_create_cmd_comp(ctx); +#else + (void)ctx; + errno = -ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_destroy_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + mlx5dv_devx_destroy_cmd_comp(cmd_comp); +#else + (void)cmd_comp; + errno = -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_query_async(struct mlx5dv_devx_obj *obj, const void *in, + size_t inlen, size_t outlen, uint64_t wr_id, + struct mlx5dv_devx_cmd_comp *cmd_comp) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_obj_query_async(obj, in, inlen, outlen, wr_id, + cmd_comp); +#else + (void)obj; + (void)in; + (void)inlen; + (void)outlen; + (void)wr_id; + (void)cmd_comp; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_get_async_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp, + struct mlx5dv_devx_async_cmd_hdr *cmd_resp, + size_t cmd_resp_len) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_get_async_cmd_comp(cmd_comp, cmd_resp, + cmd_resp_len); +#else + (void)cmd_comp; + (void)cmd_resp; + (void)cmd_resp_len; + return -ENOTSUP; +#endif +} + +static struct mlx5dv_devx_umem * +mlx5_glue_devx_umem_reg(struct ibv_context *context, void *addr, size_t size, + uint32_t access) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_umem_reg(context, addr, size, access); +#else + (void)context; + (void)addr; + (void)size; + (void)access; + errno = -ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_umem_dereg(dv_devx_umem); +#else + (void)dv_devx_umem; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_qp_query(struct ibv_qp *qp, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_QP + return mlx5dv_devx_qp_query(qp, in, inlen, out, outlen); +#else + (void)qp; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_devx_port_query(struct ibv_context *ctx, + uint32_t port_num, + struct mlx5dv_devx_port *mlx5_devx_port) +{ +#ifdef HAVE_MLX5DV_DR_DEVX_PORT + return mlx5dv_query_devx_port(ctx, port_num, mlx5_devx_port); +#else + (void)ctx; + (void)port_num; + (void)mlx5_devx_port; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_dr_dump_domain(FILE *file, void *domain) +{ +#ifdef HAVE_MLX5_DR_FLOW_DUMP + return mlx5dv_dump_dr_domain(file, domain); +#else + RTE_SET_USED(file); + RTE_SET_USED(domain); + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_query_eqn(struct ibv_context *ctx, uint32_t cpus, + uint32_t *eqn) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_query_eqn(ctx, cpus, eqn); +#else + (void)ctx; + (void)cpus; + (void)eqn; + return -ENOTSUP; +#endif +} + +static struct mlx5dv_devx_event_channel * +mlx5_glue_devx_create_event_channel(struct ibv_context *ctx, int flags) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_create_event_channel(ctx, flags); +#else + (void)ctx; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_destroy_event_channel(struct mlx5dv_devx_event_channel *eventc) +{ +#ifdef HAVE_IBV_DEVX_EVENT + mlx5dv_devx_destroy_event_channel(eventc); +#else + (void)eventc; +#endif +} + +static int +mlx5_glue_devx_subscribe_devx_event(struct mlx5dv_devx_event_channel *eventc, + struct mlx5dv_devx_obj *obj, + uint16_t events_sz, uint16_t events_num[], + uint64_t cookie) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_subscribe_devx_event(eventc, obj, events_sz, + events_num, cookie); +#else + (void)eventc; + (void)obj; + (void)events_sz; + (void)events_num; + (void)cookie; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_subscribe_devx_event_fd(struct mlx5dv_devx_event_channel *eventc, + int fd, struct mlx5dv_devx_obj *obj, + uint16_t event_num) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_subscribe_devx_event_fd(eventc, fd, obj, event_num); +#else + (void)eventc; + (void)fd; + (void)obj; + (void)event_num; + return -ENOTSUP; +#endif +} + +static ssize_t +mlx5_glue_devx_get_event(struct mlx5dv_devx_event_channel *eventc, + struct mlx5dv_devx_async_event_hdr *event_data, + size_t event_resp_len) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_get_event(eventc, event_data, event_resp_len); +#else + (void)eventc; + (void)event_data; + (void)event_resp_len; + errno = ENOTSUP; + return -1; +#endif +} + +static struct mlx5dv_devx_uar * +mlx5_glue_devx_alloc_uar(struct ibv_context *context, uint32_t flags) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_alloc_uar(context, flags); +#else + (void)context; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_free_uar(struct mlx5dv_devx_uar *devx_uar) +{ +#ifdef HAVE_IBV_DEVX_OBJ + mlx5dv_devx_free_uar(devx_uar); +#else + (void)devx_uar; +#endif +} + +static struct mlx5dv_var * +mlx5_glue_dv_alloc_var(struct ibv_context *context, uint32_t flags) +{ +#ifdef HAVE_IBV_VAR + return mlx5dv_alloc_var(context, flags); +#else + (void)context; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_dv_free_var(struct mlx5dv_var *var) +{ +#ifdef HAVE_IBV_VAR + mlx5dv_free_var(var); +#else + (void)var; + errno = ENOTSUP; +#endif +} + +__rte_cache_aligned +const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue) { + .version = MLX5_GLUE_VERSION, + .fork_init = mlx5_glue_fork_init, + .alloc_pd = mlx5_glue_alloc_pd, + .dealloc_pd = mlx5_glue_dealloc_pd, + .get_device_list = mlx5_glue_get_device_list, + .free_device_list = mlx5_glue_free_device_list, + .open_device = mlx5_glue_open_device, + .close_device = mlx5_glue_close_device, + .query_device = mlx5_glue_query_device, + .query_device_ex = mlx5_glue_query_device_ex, + .query_rt_values_ex = mlx5_glue_query_rt_values_ex, + .query_port = mlx5_glue_query_port, + .create_comp_channel = mlx5_glue_create_comp_channel, + .destroy_comp_channel = mlx5_glue_destroy_comp_channel, + .create_cq = mlx5_glue_create_cq, + .destroy_cq = mlx5_glue_destroy_cq, + .get_cq_event = mlx5_glue_get_cq_event, + .ack_cq_events = mlx5_glue_ack_cq_events, + .create_rwq_ind_table = mlx5_glue_create_rwq_ind_table, + .destroy_rwq_ind_table = mlx5_glue_destroy_rwq_ind_table, + .create_wq = mlx5_glue_create_wq, + .destroy_wq = mlx5_glue_destroy_wq, + .modify_wq = mlx5_glue_modify_wq, + .create_flow = mlx5_glue_create_flow, + .destroy_flow = mlx5_glue_destroy_flow, + .destroy_flow_action = mlx5_glue_destroy_flow_action, + .create_qp = mlx5_glue_create_qp, + .create_qp_ex = mlx5_glue_create_qp_ex, + .destroy_qp = mlx5_glue_destroy_qp, + .modify_qp = mlx5_glue_modify_qp, + .reg_mr = mlx5_glue_reg_mr, + .alloc_null_mr = mlx5_glue_alloc_null_mr, + .dereg_mr = mlx5_glue_dereg_mr, + .create_counter_set = mlx5_glue_create_counter_set, + .destroy_counter_set = mlx5_glue_destroy_counter_set, + .describe_counter_set = mlx5_glue_describe_counter_set, + .query_counter_set = mlx5_glue_query_counter_set, + .create_counters = mlx5_glue_create_counters, + .destroy_counters = mlx5_glue_destroy_counters, + .attach_counters = mlx5_glue_attach_counters, + .query_counters = mlx5_glue_query_counters, + .ack_async_event = mlx5_glue_ack_async_event, + .get_async_event = mlx5_glue_get_async_event, + .port_state_str = mlx5_glue_port_state_str, + .cq_ex_to_cq = mlx5_glue_cq_ex_to_cq, + .dr_create_flow_action_dest_flow_tbl = + mlx5_glue_dr_create_flow_action_dest_flow_tbl, + .dr_create_flow_action_dest_port = + mlx5_glue_dr_create_flow_action_dest_port, + .dr_create_flow_action_drop = + mlx5_glue_dr_create_flow_action_drop, + .dr_create_flow_action_push_vlan = + mlx5_glue_dr_create_flow_action_push_vlan, + .dr_create_flow_action_pop_vlan = + mlx5_glue_dr_create_flow_action_pop_vlan, + .dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl, + .dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl, + .dr_create_domain = mlx5_glue_dr_create_domain, + .dr_destroy_domain = mlx5_glue_dr_destroy_domain, + .dv_create_cq = mlx5_glue_dv_create_cq, + .dv_create_wq = mlx5_glue_dv_create_wq, + .dv_query_device = mlx5_glue_dv_query_device, + .dv_set_context_attr = mlx5_glue_dv_set_context_attr, + .dv_init_obj = mlx5_glue_dv_init_obj, + .dv_create_qp = mlx5_glue_dv_create_qp, + .dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher, + .dv_create_flow = mlx5_glue_dv_create_flow, + .dv_create_flow_action_counter = + mlx5_glue_dv_create_flow_action_counter, + .dv_create_flow_action_dest_ibv_qp = + mlx5_glue_dv_create_flow_action_dest_ibv_qp, + .dv_create_flow_action_dest_devx_tir = + mlx5_glue_dv_create_flow_action_dest_devx_tir, + .dv_create_flow_action_modify_header = + mlx5_glue_dv_create_flow_action_modify_header, + .dv_create_flow_action_packet_reformat = + mlx5_glue_dv_create_flow_action_packet_reformat, + .dv_create_flow_action_tag = mlx5_glue_dv_create_flow_action_tag, + .dv_create_flow_action_meter = mlx5_glue_dv_create_flow_action_meter, + .dv_modify_flow_action_meter = mlx5_glue_dv_modify_flow_action_meter, + .dv_destroy_flow = mlx5_glue_dv_destroy_flow, + .dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher, + .dv_open_device = mlx5_glue_dv_open_device, + .devx_obj_create = mlx5_glue_devx_obj_create, + .devx_obj_destroy = mlx5_glue_devx_obj_destroy, + .devx_obj_query = mlx5_glue_devx_obj_query, + .devx_obj_modify = mlx5_glue_devx_obj_modify, + .devx_general_cmd = mlx5_glue_devx_general_cmd, + .devx_create_cmd_comp = mlx5_glue_devx_create_cmd_comp, + .devx_destroy_cmd_comp = mlx5_glue_devx_destroy_cmd_comp, + .devx_obj_query_async = mlx5_glue_devx_obj_query_async, + .devx_get_async_cmd_comp = mlx5_glue_devx_get_async_cmd_comp, + .devx_umem_reg = mlx5_glue_devx_umem_reg, + .devx_umem_dereg = mlx5_glue_devx_umem_dereg, + .devx_qp_query = mlx5_glue_devx_qp_query, + .devx_port_query = mlx5_glue_devx_port_query, + .dr_dump_domain = mlx5_glue_dr_dump_domain, + .devx_query_eqn = mlx5_glue_devx_query_eqn, + .devx_create_event_channel = mlx5_glue_devx_create_event_channel, + .devx_destroy_event_channel = mlx5_glue_devx_destroy_event_channel, + .devx_subscribe_devx_event = mlx5_glue_devx_subscribe_devx_event, + .devx_subscribe_devx_event_fd = mlx5_glue_devx_subscribe_devx_event_fd, + .devx_get_event = mlx5_glue_devx_get_event, + .devx_alloc_uar = mlx5_glue_devx_alloc_uar, + .devx_free_uar = mlx5_glue_devx_free_uar, + .dv_alloc_var = mlx5_glue_dv_alloc_var, + .dv_free_var = mlx5_glue_dv_free_var, +}; diff --git a/drivers/common/mlx5/linux/mlx5_glue.h b/drivers/common/mlx5/linux/mlx5_glue.h new file mode 100644 index 0000000..81d6a22 --- /dev/null +++ b/drivers/common/mlx5/linux/mlx5_glue.h @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#ifndef MLX5_GLUE_H_ +#define MLX5_GLUE_H_ + +#include +#include +/* Verbs headers do not support -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include + +#include "mlx5_autoconf.h" + +#ifndef MLX5_GLUE_VERSION +#define MLX5_GLUE_VERSION "" +#endif + +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 +struct ibv_counter_set; +struct ibv_counter_set_data; +struct ibv_counter_set_description; +struct ibv_counter_set_init_attr; +struct ibv_query_counter_set_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 +struct ibv_counters; +struct ibv_counters_init_attr; +struct ibv_counter_attach_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_TUNNEL_SUPPORT +struct mlx5dv_qp_init_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT +struct mlx5dv_wq_init_attr; +#endif + +#ifndef HAVE_IBV_FLOW_DV_SUPPORT +struct mlx5dv_flow_matcher; +struct mlx5dv_flow_matcher_attr; +struct mlx5dv_flow_action_attr; +struct mlx5dv_flow_match_parameters; +struct mlx5dv_dr_flow_meter_attr; +struct ibv_flow_action; +enum mlx5dv_flow_action_packet_reformat_type { packet_reformat_type = 0, }; +enum mlx5dv_flow_table_type { flow_table_type = 0, }; +#endif + +#ifndef HAVE_IBV_FLOW_DEVX_COUNTERS +#define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0 +#endif + +#ifndef HAVE_IBV_DEVX_OBJ +struct mlx5dv_devx_obj; +struct mlx5dv_devx_umem { uint32_t umem_id; }; +struct mlx5dv_devx_uar { void *reg_addr; void *base_addr; uint32_t page_id; }; +#endif + +#ifndef HAVE_IBV_DEVX_ASYNC +struct mlx5dv_devx_cmd_comp; +struct mlx5dv_devx_async_cmd_hdr; +#endif + +#ifndef HAVE_MLX5DV_DR +enum mlx5dv_dr_domain_type { unused, }; +struct mlx5dv_dr_domain; +#endif + +#ifndef HAVE_MLX5DV_DR_DEVX_PORT +struct mlx5dv_devx_port; +#endif + +#ifndef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER +struct mlx5dv_dr_flow_meter_attr; +#endif + +#ifndef HAVE_IBV_DEVX_EVENT +struct mlx5dv_devx_event_channel { int fd; }; +struct mlx5dv_devx_async_event_hdr; +#define MLX5DV_DEVX_CREATE_EVENT_CHANNEL_FLAGS_OMIT_EV_DATA 1 +#endif + +#ifndef HAVE_IBV_VAR +struct mlx5dv_var { uint32_t page_id; uint32_t length; off_t mmap_off; + uint64_t comp_mask; }; +#endif + +#ifndef HAVE_IBV_RELAXED_ORDERING +#define IBV_ACCESS_RELAXED_ORDERING 0 +#endif + +/* LIB_GLUE_VERSION must be updated every time this structure is modified. */ +struct mlx5_glue { + const char *version; + int (*fork_init)(void); + struct ibv_pd *(*alloc_pd)(struct ibv_context *context); + int (*dealloc_pd)(struct ibv_pd *pd); + struct ibv_device **(*get_device_list)(int *num_devices); + void (*free_device_list)(struct ibv_device **list); + struct ibv_context *(*open_device)(struct ibv_device *device); + int (*close_device)(struct ibv_context *context); + int (*query_device)(struct ibv_context *context, + struct ibv_device_attr *device_attr); + int (*query_device_ex)(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr); + int (*query_rt_values_ex)(struct ibv_context *context, + struct ibv_values_ex *values); + int (*query_port)(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr); + struct ibv_comp_channel *(*create_comp_channel) + (struct ibv_context *context); + int (*destroy_comp_channel)(struct ibv_comp_channel *channel); + struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, + void *cq_context, + struct ibv_comp_channel *channel, + int comp_vector); + int (*destroy_cq)(struct ibv_cq *cq); + int (*get_cq_event)(struct ibv_comp_channel *channel, + struct ibv_cq **cq, void **cq_context); + void (*ack_cq_events)(struct ibv_cq *cq, unsigned int nevents); + struct ibv_rwq_ind_table *(*create_rwq_ind_table) + (struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr); + int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); + struct ibv_wq *(*create_wq)(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr); + int (*destroy_wq)(struct ibv_wq *wq); + int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); + struct ibv_flow *(*create_flow)(struct ibv_qp *qp, + struct ibv_flow_attr *flow); + int (*destroy_flow)(struct ibv_flow *flow_id); + int (*destroy_flow_action)(void *action); + struct ibv_qp *(*create_qp)(struct ibv_pd *pd, + struct ibv_qp_init_attr *qp_init_attr); + struct ibv_qp *(*create_qp_ex) + (struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex); + int (*destroy_qp)(struct ibv_qp *qp); + int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask); + struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, + size_t length, int access); + struct ibv_mr *(*alloc_null_mr)(struct ibv_pd *pd); + int (*dereg_mr)(struct ibv_mr *mr); + struct ibv_counter_set *(*create_counter_set) + (struct ibv_context *context, + struct ibv_counter_set_init_attr *init_attr); + int (*destroy_counter_set)(struct ibv_counter_set *cs); + int (*describe_counter_set) + (struct ibv_context *context, + uint16_t counter_set_id, + struct ibv_counter_set_description *cs_desc); + int (*query_counter_set)(struct ibv_query_counter_set_attr *query_attr, + struct ibv_counter_set_data *cs_data); + struct ibv_counters *(*create_counters) + (struct ibv_context *context, + struct ibv_counters_init_attr *init_attr); + int (*destroy_counters)(struct ibv_counters *counters); + int (*attach_counters)(struct ibv_counters *counters, + struct ibv_counter_attach_attr *attr, + struct ibv_flow *flow); + int (*query_counters)(struct ibv_counters *counters, + uint64_t *counters_value, + uint32_t ncounters, + uint32_t flags); + void (*ack_async_event)(struct ibv_async_event *event); + int (*get_async_event)(struct ibv_context *context, + struct ibv_async_event *event); + const char *(*port_state_str)(enum ibv_port_state port_state); + struct ibv_cq *(*cq_ex_to_cq)(struct ibv_cq_ex *cq); + void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); + void *(*dr_create_flow_action_dest_port)(void *domain, + uint32_t port); + void *(*dr_create_flow_action_drop)(); + void *(*dr_create_flow_action_push_vlan) + (struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag); + void *(*dr_create_flow_action_pop_vlan)(); + void *(*dr_create_flow_tbl)(void *domain, uint32_t level); + int (*dr_destroy_flow_tbl)(void *tbl); + void *(*dr_create_domain)(struct ibv_context *ctx, + enum mlx5dv_dr_domain_type domain); + int (*dr_destroy_domain)(void *domain); + struct ibv_cq_ex *(*dv_create_cq) + (struct ibv_context *context, + struct ibv_cq_init_attr_ex *cq_attr, + struct mlx5dv_cq_init_attr *mlx5_cq_attr); + struct ibv_wq *(*dv_create_wq) + (struct ibv_context *context, + struct ibv_wq_init_attr *wq_attr, + struct mlx5dv_wq_init_attr *mlx5_wq_attr); + int (*dv_query_device)(struct ibv_context *ctx_in, + struct mlx5dv_context *attrs_out); + int (*dv_set_context_attr)(struct ibv_context *ibv_ctx, + enum mlx5dv_set_ctx_attr_type type, + void *attr); + int (*dv_init_obj)(struct mlx5dv_obj *obj, uint64_t obj_type); + struct ibv_qp *(*dv_create_qp) + (struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex, + struct mlx5dv_qp_init_attr *dv_qp_init_attr); + void *(*dv_create_flow_matcher) + (struct ibv_context *context, + struct mlx5dv_flow_matcher_attr *matcher_attr, + void *tbl); + void *(*dv_create_flow)(void *matcher, void *match_value, + size_t num_actions, void *actions[]); + void *(*dv_create_flow_action_counter)(void *obj, uint32_t offset); + void *(*dv_create_flow_action_dest_ibv_qp)(void *qp); + void *(*dv_create_flow_action_dest_devx_tir)(void *tir); + void *(*dv_create_flow_action_modify_header) + (struct ibv_context *ctx, enum mlx5dv_flow_table_type ft_type, + void *domain, uint64_t flags, size_t actions_sz, + uint64_t actions[]); + void *(*dv_create_flow_action_packet_reformat) + (struct ibv_context *ctx, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type, + struct mlx5dv_dr_domain *domain, + uint32_t flags, size_t data_sz, void *data); + void *(*dv_create_flow_action_tag)(uint32_t tag); + void *(*dv_create_flow_action_meter) + (struct mlx5dv_dr_flow_meter_attr *attr); + int (*dv_modify_flow_action_meter)(void *action, + struct mlx5dv_dr_flow_meter_attr *attr, uint64_t modify_bits); + int (*dv_destroy_flow)(void *flow); + int (*dv_destroy_flow_matcher)(void *matcher); + struct ibv_context *(*dv_open_device)(struct ibv_device *device); + struct mlx5dv_var *(*dv_alloc_var)(struct ibv_context *context, + uint32_t flags); + void (*dv_free_var)(struct mlx5dv_var *var); + struct mlx5dv_devx_uar *(*devx_alloc_uar)(struct ibv_context *context, + uint32_t flags); + void (*devx_free_uar)(struct mlx5dv_devx_uar *devx_uar); + struct mlx5dv_devx_obj *(*devx_obj_create) + (struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_obj_destroy)(struct mlx5dv_devx_obj *obj); + int (*devx_obj_query)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_obj_modify)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_general_cmd)(struct ibv_context *context, + const void *in, size_t inlen, + void *out, size_t outlen); + struct mlx5dv_devx_cmd_comp *(*devx_create_cmd_comp) + (struct ibv_context *context); + void (*devx_destroy_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp); + int (*devx_obj_query_async)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + size_t outlen, uint64_t wr_id, + struct mlx5dv_devx_cmd_comp *cmd_comp); + int (*devx_get_async_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp, + struct mlx5dv_devx_async_cmd_hdr *resp, + size_t cmd_resp_len); + struct mlx5dv_devx_umem *(*devx_umem_reg)(struct ibv_context *context, + void *addr, size_t size, + uint32_t access); + int (*devx_umem_dereg)(struct mlx5dv_devx_umem *dv_devx_umem); + int (*devx_qp_query)(struct ibv_qp *qp, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_port_query)(struct ibv_context *ctx, + uint32_t port_num, + struct mlx5dv_devx_port *mlx5_devx_port); + int (*dr_dump_domain)(FILE *file, void *domain); + int (*devx_query_eqn)(struct ibv_context *context, uint32_t cpus, + uint32_t *eqn); + struct mlx5dv_devx_event_channel *(*devx_create_event_channel) + (struct ibv_context *context, int flags); + void (*devx_destroy_event_channel) + (struct mlx5dv_devx_event_channel *event_channel); + int (*devx_subscribe_devx_event) + (struct mlx5dv_devx_event_channel *event_channel, + struct mlx5dv_devx_obj *obj, + uint16_t events_sz, + uint16_t events_num[], + uint64_t cookie); + int (*devx_subscribe_devx_event_fd) + (struct mlx5dv_devx_event_channel *event_channel, + int fd, + struct mlx5dv_devx_obj *obj, + uint16_t event_num); + ssize_t (*devx_get_event) + (struct mlx5dv_devx_event_channel *event_channel, + struct mlx5dv_devx_async_event_hdr *event_data, + size_t event_resp_len); +}; + +extern const struct mlx5_glue *mlx5_glue; + +#endif /* MLX5_GLUE_H_ */ diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 5a802ba..9806865 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -1,65 +1,23 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright 2019 Mellanox Technologies, Ltd -if not is_linux +if not (is_linux or is_windows) build = false - reason = 'only supported on Linux' + reason = 'only supported on Linux and Windows' subdir_done() endif -static_ibverbs = (get_option('ibverbs_link') == 'static') -dlopen_ibverbs = (get_option('ibverbs_link') == 'dlopen') -LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so' -LIB_GLUE_VERSION = '20.02.0' -LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION -if dlopen_ibverbs - dpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1) - cflags += [ - '-DMLX5_GLUE="@0@"'.format(LIB_GLUE), - '-DMLX5_GLUE_VERSION="@0@"'.format(LIB_GLUE_VERSION), - ] -endif - -libnames = [ 'mlx5', 'ibverbs' ] -libs = [] -foreach libname:libnames - lib = dependency('lib' + libname, static:static_ibverbs, required:false) - if not lib.found() and not static_ibverbs - lib = cc.find_library(libname, required:false) - endif - if lib.found() - libs += lib - if not static_ibverbs and not dlopen_ibverbs - ext_deps += lib - endif - else - build = false - reason = 'missing dependency, "' + libname + '"' - subdir_done() - endif -endforeach -if static_ibverbs or dlopen_ibverbs - # Build without adding shared libs to Requires.private - ibv_cflags = run_command(pkgconf, '--cflags', 'libibverbs').stdout() - ext_deps += declare_dependency(compile_args: ibv_cflags.split()) -endif -if static_ibverbs - # Add static deps ldflags to internal apps and Libs.private - ibv_ldflags = run_command(ldflags_ibverbs_static, check:true).stdout() - ext_deps += declare_dependency(link_args:ibv_ldflags.split()) -endif +allow_experimental_apis = true deps += ['hash', 'pci', 'net', 'eal', 'kvargs'] -sources = files( +sources += files( 'mlx5_devx_cmds.c', 'mlx5_common.c', 'mlx5_nl.c', 'mlx5_common_mp.c', 'mlx5_common_mr.c', ) -if not dlopen_ibverbs - sources += files('mlx5_glue.c') -endif + cflags_options = [ '-std=c11', '-Wno-strict-prototypes', @@ -77,151 +35,5 @@ if get_option('buildtype').contains('debug') else cflags += [ '-UPEDANTIC' ] endif -# To maintain the compatibility with the make build system -# mlx5_autoconf.h file is still generated. -# input array for meson member search: -# [ "MACRO to define if found", "header for the search", -# "symbol to search", "struct member to search" ] -has_member_args = [ - [ 'HAVE_IBV_MLX5_MOD_SWP', 'infiniband/mlx5dv.h', - 'struct mlx5dv_sw_parsing_caps', 'sw_parsing_offloads' ], - [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V42', 'infiniband/verbs.h', - 'struct ibv_counter_set_init_attr', 'counter_set_id' ], - [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V45', 'infiniband/verbs.h', - 'struct ibv_counters_init_attr', 'comp_mask' ], -] -# input array for meson symbol search: -# [ "MACRO to define if found", "header for the search", -# "symbol to search" ] -has_sym_args = [ - [ 'HAVE_IBV_RELAXED_ORDERING', 'infiniband/verbs.h', - 'IBV_ACCESS_RELAXED_ORDERING ' ], - [ 'HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT', 'infiniband/mlx5dv.h', - 'MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX' ], - [ 'HAVE_IBV_DEVICE_TUNNEL_SUPPORT', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS' ], - [ 'HAVE_IBV_MLX5_MOD_MPW', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED' ], - [ 'HAVE_IBV_MLX5_MOD_CQE_128B_COMP', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP' ], - [ 'HAVE_IBV_MLX5_MOD_CQE_128B_PAD', 'infiniband/mlx5dv.h', - 'MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD' ], - [ 'HAVE_IBV_FLOW_DV_SUPPORT', 'infiniband/mlx5dv.h', - 'mlx5dv_create_flow_action_packet_reformat' ], - [ 'HAVE_IBV_DEVICE_MPLS_SUPPORT', 'infiniband/verbs.h', - 'IBV_FLOW_SPEC_MPLS' ], - [ 'HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING', 'infiniband/verbs.h', - 'IBV_WQ_FLAGS_PCI_WRITE_END_PADDING' ], - [ 'HAVE_IBV_WQ_FLAG_RX_END_PADDING', 'infiniband/verbs.h', - 'IBV_WQ_FLAG_RX_END_PADDING' ], - [ 'HAVE_MLX5DV_DR_DEVX_PORT', 'infiniband/mlx5dv.h', - 'mlx5dv_query_devx_port' ], - [ 'HAVE_IBV_DEVX_OBJ', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_obj_create' ], - [ 'HAVE_IBV_FLOW_DEVX_COUNTERS', 'infiniband/mlx5dv.h', - 'MLX5DV_FLOW_ACTION_COUNTERS_DEVX' ], - [ 'HAVE_IBV_DEVX_ASYNC', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_obj_query_async' ], - [ 'HAVE_IBV_DEVX_QP', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_qp_query' ], - [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_dest_devx_tir' ], - [ 'HAVE_IBV_DEVX_EVENT', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_get_event' ], - [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_flow_meter' ], - [ 'HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD', 'infiniband/mlx5dv.h', - 'MLX5_MMAP_GET_NC_PAGES_CMD' ], - [ 'HAVE_MLX5DV_DR', 'infiniband/mlx5dv.h', - 'MLX5DV_DR_DOMAIN_TYPE_NIC_RX' ], - [ 'HAVE_MLX5DV_DR_ESWITCH', 'infiniband/mlx5dv.h', - 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], - [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_push_vlan' ], - [ 'HAVE_IBV_VAR', 'infiniband/mlx5dv.h', 'mlx5dv_alloc_var' ], - [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseKR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseCR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseSR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseSR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseLR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseLR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseKR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseKR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseCR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseCR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseSR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseSR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseLR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseLR4_Full' ], - [ 'HAVE_ETHTOOL_LINK_MODE_25G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_25000baseCR_Full_BIT' ], - [ 'HAVE_ETHTOOL_LINK_MODE_50G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT' ], - [ 'HAVE_ETHTOOL_LINK_MODE_100G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT' ], - [ 'HAVE_IFLA_NUM_VF', 'linux/if_link.h', - 'IFLA_NUM_VF' ], - [ 'HAVE_IFLA_EXT_MASK', 'linux/if_link.h', - 'IFLA_EXT_MASK' ], - [ 'HAVE_IFLA_PHYS_SWITCH_ID', 'linux/if_link.h', - 'IFLA_PHYS_SWITCH_ID' ], - [ 'HAVE_IFLA_PHYS_PORT_NAME', 'linux/if_link.h', - 'IFLA_PHYS_PORT_NAME' ], - [ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h', - 'RDMA_NL_NLDEV' ], - [ 'HAVE_RDMA_NLDEV_CMD_GET', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_CMD_GET' ], - [ 'HAVE_RDMA_NLDEV_CMD_PORT_GET', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_CMD_PORT_GET' ], - [ 'HAVE_RDMA_NLDEV_ATTR_DEV_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_DEV_INDEX' ], - [ 'HAVE_RDMA_NLDEV_ATTR_DEV_NAME', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_DEV_NAME' ], - [ 'HAVE_RDMA_NLDEV_ATTR_PORT_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_PORT_INDEX' ], - [ 'HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_NDEV_INDEX' ], - [ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h', - 'mlx5dv_dump_dr_domain'], - [ 'HAVE_DEVLINK', 'linux/devlink.h', 'DEVLINK_GENL_NAME' ], -] -config = configuration_data() -foreach arg:has_sym_args - config.set(arg[0], cc.has_header_symbol(arg[1], arg[2], - dependencies: libs)) -endforeach -foreach arg:has_member_args - file_prefix = '#include <' + arg[1] + '>' - config.set(arg[0], cc.has_member(arg[2], arg[3], - prefix : file_prefix, dependencies: libs)) -endforeach -configure_file(output : 'mlx5_autoconf.h', configuration : config) -# Build Glue Library -if dlopen_ibverbs - dlopen_name = 'mlx5_glue' - dlopen_lib_name = 'rte_pmd_@0@'.format(dlopen_name) - dlopen_so_version = LIB_GLUE_VERSION - dlopen_sources = files('mlx5_glue.c') - dlopen_install_dir = [ eal_pmd_path + '-glue' ] - dlopen_includes = [global_inc] - dlopen_includes += include_directories( - '../../../lib/librte_eal/include/generic', - ) - shared_lib = shared_library( - dlopen_lib_name, - dlopen_sources, - include_directories: dlopen_includes, - c_args: cflags, - dependencies: libs, - link_args: [ - '-Wl,-export-dynamic', - '-Wl,-h,@0@'.format(LIB_GLUE), - ], - soversion: dlopen_so_version, - install: true, - install_dir: dlopen_install_dir, - ) -endif +subdir(exec_env) diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c deleted file mode 100644 index f270f67..0000000 --- a/drivers/common/mlx5/mlx5_glue.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include -/* - * Not needed by this file; included to work around the lack of off_t - * definition for mlx5dv.h with unpatched rdma-core versions. - */ -#include - -#include "mlx5_glue.h" - -static int -mlx5_glue_fork_init(void) -{ - return ibv_fork_init(); -} - -static struct ibv_pd * -mlx5_glue_alloc_pd(struct ibv_context *context) -{ - return ibv_alloc_pd(context); -} - -static int -mlx5_glue_dealloc_pd(struct ibv_pd *pd) -{ - return ibv_dealloc_pd(pd); -} - -static struct ibv_device ** -mlx5_glue_get_device_list(int *num_devices) -{ - return ibv_get_device_list(num_devices); -} - -static void -mlx5_glue_free_device_list(struct ibv_device **list) -{ - ibv_free_device_list(list); -} - -static struct ibv_context * -mlx5_glue_open_device(struct ibv_device *device) -{ - return ibv_open_device(device); -} - -static int -mlx5_glue_close_device(struct ibv_context *context) -{ - return ibv_close_device(context); -} - -static int -mlx5_glue_query_device(struct ibv_context *context, - struct ibv_device_attr *device_attr) -{ - return ibv_query_device(context, device_attr); -} - -static int -mlx5_glue_query_device_ex(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr) -{ - return ibv_query_device_ex(context, input, attr); -} - -static int -mlx5_glue_query_rt_values_ex(struct ibv_context *context, - struct ibv_values_ex *values) -{ - return ibv_query_rt_values_ex(context, values); -} - -static int -mlx5_glue_query_port(struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr) -{ - return ibv_query_port(context, port_num, port_attr); -} - -static struct ibv_comp_channel * -mlx5_glue_create_comp_channel(struct ibv_context *context) -{ - return ibv_create_comp_channel(context); -} - -static int -mlx5_glue_destroy_comp_channel(struct ibv_comp_channel *channel) -{ - return ibv_destroy_comp_channel(channel); -} - -static struct ibv_cq * -mlx5_glue_create_cq(struct ibv_context *context, int cqe, void *cq_context, - struct ibv_comp_channel *channel, int comp_vector) -{ - return ibv_create_cq(context, cqe, cq_context, channel, comp_vector); -} - -static int -mlx5_glue_destroy_cq(struct ibv_cq *cq) -{ - return ibv_destroy_cq(cq); -} - -static int -mlx5_glue_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, - void **cq_context) -{ - return ibv_get_cq_event(channel, cq, cq_context); -} - -static void -mlx5_glue_ack_cq_events(struct ibv_cq *cq, unsigned int nevents) -{ - ibv_ack_cq_events(cq, nevents); -} - -static struct ibv_rwq_ind_table * -mlx5_glue_create_rwq_ind_table(struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr) -{ - return ibv_create_rwq_ind_table(context, init_attr); -} - -static int -mlx5_glue_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) -{ - return ibv_destroy_rwq_ind_table(rwq_ind_table); -} - -static struct ibv_wq * -mlx5_glue_create_wq(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr) -{ - return ibv_create_wq(context, wq_init_attr); -} - -static int -mlx5_glue_destroy_wq(struct ibv_wq *wq) -{ - return ibv_destroy_wq(wq); -} -static int -mlx5_glue_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr) -{ - return ibv_modify_wq(wq, wq_attr); -} - -static struct ibv_flow * -mlx5_glue_create_flow(struct ibv_qp *qp, struct ibv_flow_attr *flow) -{ - return ibv_create_flow(qp, flow); -} - -static int -mlx5_glue_destroy_flow(struct ibv_flow *flow_id) -{ - return ibv_destroy_flow(flow_id); -} - -static int -mlx5_glue_destroy_flow_action(void *action) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_destroy(action); -#else - struct mlx5dv_flow_action_attr *attr = action; - int res = 0; - switch (attr->type) { - case MLX5DV_FLOW_ACTION_TAG: - break; - default: - res = ibv_destroy_flow_action(attr->action); - break; - } - free(action); - return res; -#endif -#else - (void)action; - return ENOTSUP; -#endif -} - -static struct ibv_qp * -mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) -{ - return ibv_create_qp(pd, qp_init_attr); -} - -static struct ibv_qp * -mlx5_glue_create_qp_ex(struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex) -{ - return ibv_create_qp_ex(context, qp_init_attr_ex); -} - -static int -mlx5_glue_destroy_qp(struct ibv_qp *qp) -{ - return ibv_destroy_qp(qp); -} - -static int -mlx5_glue_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) -{ - return ibv_modify_qp(qp, attr, attr_mask); -} - -static struct ibv_mr * -mlx5_glue_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access) -{ - return ibv_reg_mr(pd, addr, length, access); -} - -static struct ibv_mr * -mlx5_glue_alloc_null_mr(struct ibv_pd *pd) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return ibv_alloc_null_mr(pd); -#else - (void)pd; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dereg_mr(struct ibv_mr *mr) -{ - return ibv_dereg_mr(mr); -} - -static struct ibv_counter_set * -mlx5_glue_create_counter_set(struct ibv_context *context, - struct ibv_counter_set_init_attr *init_attr) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)context; - (void)init_attr; - return NULL; -#else - return ibv_create_counter_set(context, init_attr); -#endif -} - -static int -mlx5_glue_destroy_counter_set(struct ibv_counter_set *cs) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)cs; - return ENOTSUP; -#else - return ibv_destroy_counter_set(cs); -#endif -} - -static int -mlx5_glue_describe_counter_set(struct ibv_context *context, - uint16_t counter_set_id, - struct ibv_counter_set_description *cs_desc) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)context; - (void)counter_set_id; - (void)cs_desc; - return ENOTSUP; -#else - return ibv_describe_counter_set(context, counter_set_id, cs_desc); -#endif -} - -static int -mlx5_glue_query_counter_set(struct ibv_query_counter_set_attr *query_attr, - struct ibv_counter_set_data *cs_data) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)query_attr; - (void)cs_data; - return ENOTSUP; -#else - return ibv_query_counter_set(query_attr, cs_data); -#endif -} - -static struct ibv_counters * -mlx5_glue_create_counters(struct ibv_context *context, - struct ibv_counters_init_attr *init_attr) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)context; - (void)init_attr; - errno = ENOTSUP; - return NULL; -#else - return ibv_create_counters(context, init_attr); -#endif -} - -static int -mlx5_glue_destroy_counters(struct ibv_counters *counters) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - return ENOTSUP; -#else - return ibv_destroy_counters(counters); -#endif -} - -static int -mlx5_glue_attach_counters(struct ibv_counters *counters, - struct ibv_counter_attach_attr *attr, - struct ibv_flow *flow) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - (void)attr; - (void)flow; - return ENOTSUP; -#else - return ibv_attach_counters_point_flow(counters, attr, flow); -#endif -} - -static int -mlx5_glue_query_counters(struct ibv_counters *counters, - uint64_t *counters_value, - uint32_t ncounters, - uint32_t flags) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - (void)counters_value; - (void)ncounters; - (void)flags; - return ENOTSUP; -#else - return ibv_read_counters(counters, counters_value, ncounters, flags); -#endif -} - -static void -mlx5_glue_ack_async_event(struct ibv_async_event *event) -{ - ibv_ack_async_event(event); -} - -static int -mlx5_glue_get_async_event(struct ibv_context *context, - struct ibv_async_event *event) -{ - return ibv_get_async_event(context, event); -} - -static const char * -mlx5_glue_port_state_str(enum ibv_port_state port_state) -{ - return ibv_port_state_str(port_state); -} - -static struct ibv_cq * -mlx5_glue_cq_ex_to_cq(struct ibv_cq_ex *cq) -{ - return ibv_cq_ex_to_cq(cq); -} - -static void * -mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_dest_table(tbl); -#else - (void)tbl; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_dest_port(void *domain, uint32_t port) -{ -#ifdef HAVE_MLX5DV_DR_DEVX_PORT - return mlx5dv_dr_action_create_dest_ib_port(domain, port); -#else -#ifdef HAVE_MLX5DV_DR_ESWITCH - return mlx5dv_dr_action_create_dest_vport(domain, port); -#else - (void)domain; - (void)port; - errno = ENOTSUP; - return NULL; -#endif -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_drop(void) -{ -#ifdef HAVE_MLX5DV_DR_ESWITCH - return mlx5dv_dr_action_create_drop(); -#else - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_push_vlan(struct mlx5dv_dr_domain *domain, - rte_be32_t vlan_tag) -{ -#ifdef HAVE_MLX5DV_DR_VLAN - return mlx5dv_dr_action_create_push_vlan(domain, vlan_tag); -#else - (void)domain; - (void)vlan_tag; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_pop_vlan(void) -{ -#ifdef HAVE_MLX5DV_DR_VLAN - return mlx5dv_dr_action_create_pop_vlan(); -#else - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_table_create(domain, level); -#else - (void)domain; - (void)level; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dr_destroy_flow_tbl(void *tbl) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_table_destroy(tbl); -#else - (void)tbl; - errno = ENOTSUP; - return errno; -#endif -} - -static void * -mlx5_glue_dr_create_domain(struct ibv_context *ctx, - enum mlx5dv_dr_domain_type domain) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_domain_create(ctx, domain); -#else - (void)ctx; - (void)domain; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dr_destroy_domain(void *domain) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_domain_destroy(domain); -#else - (void)domain; - errno = ENOTSUP; - return errno; -#endif -} - -static struct ibv_cq_ex * -mlx5_glue_dv_create_cq(struct ibv_context *context, - struct ibv_cq_init_attr_ex *cq_attr, - struct mlx5dv_cq_init_attr *mlx5_cq_attr) -{ - return mlx5dv_create_cq(context, cq_attr, mlx5_cq_attr); -} - -static struct ibv_wq * -mlx5_glue_dv_create_wq(struct ibv_context *context, - struct ibv_wq_init_attr *wq_attr, - struct mlx5dv_wq_init_attr *mlx5_wq_attr) -{ -#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT - (void)context; - (void)wq_attr; - (void)mlx5_wq_attr; - errno = ENOTSUP; - return NULL; -#else - return mlx5dv_create_wq(context, wq_attr, mlx5_wq_attr); -#endif -} - -static int -mlx5_glue_dv_query_device(struct ibv_context *ctx, - struct mlx5dv_context *attrs_out) -{ - return mlx5dv_query_device(ctx, attrs_out); -} - -static int -mlx5_glue_dv_set_context_attr(struct ibv_context *ibv_ctx, - enum mlx5dv_set_ctx_attr_type type, void *attr) -{ - return mlx5dv_set_context_attr(ibv_ctx, type, attr); -} - -static int -mlx5_glue_dv_init_obj(struct mlx5dv_obj *obj, uint64_t obj_type) -{ - return mlx5dv_init_obj(obj, obj_type); -} - -static struct ibv_qp * -mlx5_glue_dv_create_qp(struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex, - struct mlx5dv_qp_init_attr *dv_qp_init_attr) -{ -#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT - return mlx5dv_create_qp(context, qp_init_attr_ex, dv_qp_init_attr); -#else - (void)context; - (void)qp_init_attr_ex; - (void)dv_qp_init_attr; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_matcher(struct ibv_context *context, - struct mlx5dv_flow_matcher_attr *matcher_attr, - void *tbl) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)context; - return mlx5dv_dr_matcher_create(tbl, matcher_attr->priority, - matcher_attr->match_criteria_enable, - matcher_attr->match_mask); -#else - (void)tbl; - return mlx5dv_create_flow_matcher(context, matcher_attr); -#endif -#else - (void)context; - (void)matcher_attr; - (void)tbl; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow(void *matcher, - void *match_value, - size_t num_actions, - void *actions[]) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_rule_create(matcher, match_value, num_actions, - (struct mlx5dv_dr_action **)actions); -#else - struct mlx5dv_flow_action_attr actions_attr[8]; - - if (num_actions > 8) - return NULL; - for (size_t i = 0; i < num_actions; i++) - actions_attr[i] = - *((struct mlx5dv_flow_action_attr *)(actions[i])); - return mlx5dv_create_flow(matcher, match_value, - num_actions, actions_attr); -#endif -#else - (void)matcher; - (void)match_value; - (void)num_actions; - (void)actions; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_counter(void *counter_obj, uint32_t offset) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_flow_counter(counter_obj, offset); -#else - struct mlx5dv_flow_action_attr *action; - - (void)offset; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_COUNTERS_DEVX; - action->obj = counter_obj; - return action; -#endif -#else - (void)counter_obj; - (void)offset; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_dest_ibv_qp(void *qp) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_dest_ibv_qp(qp); -#else - struct mlx5dv_flow_action_attr *action; - - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_DEST_IBV_QP; - action->obj = qp; - return action; -#endif -#else - (void)qp; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_dest_devx_tir(void *tir) -{ -#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR - return mlx5dv_dr_action_create_dest_devx_tir(tir); -#else - (void)tir; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_modify_header - (struct ibv_context *ctx, - enum mlx5dv_flow_table_type ft_type, - void *domain, uint64_t flags, - size_t actions_sz, - uint64_t actions[]) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)ctx; - (void)ft_type; - return mlx5dv_dr_action_create_modify_header(domain, flags, actions_sz, - (__be64 *)actions); -#else - struct mlx5dv_flow_action_attr *action; - - (void)domain; - (void)flags; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - action->action = mlx5dv_create_flow_action_modify_header - (ctx, actions_sz, actions, ft_type); - return action; -#endif -#else - (void)ctx; - (void)ft_type; - (void)domain; - (void)flags; - (void)actions_sz; - (void)actions; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_packet_reformat - (struct ibv_context *ctx, - enum mlx5dv_flow_action_packet_reformat_type reformat_type, - enum mlx5dv_flow_table_type ft_type, - struct mlx5dv_dr_domain *domain, - uint32_t flags, size_t data_sz, void *data) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)ctx; - (void)ft_type; - return mlx5dv_dr_action_create_packet_reformat(domain, flags, - reformat_type, data_sz, - data); -#else - (void)domain; - (void)flags; - struct mlx5dv_flow_action_attr *action; - - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - action->action = mlx5dv_create_flow_action_packet_reformat - (ctx, data_sz, data, reformat_type, ft_type); - return action; -#endif -#else - (void)ctx; - (void)reformat_type; - (void)ft_type; - (void)domain; - (void)flags; - (void)data_sz; - (void)data; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_tag(uint32_t tag) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_tag(tag); -#else - struct mlx5dv_flow_action_attr *action; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_TAG; - action->tag_value = tag; - return action; -#endif -#endif - (void)tag; - errno = ENOTSUP; - return NULL; -} - -static void * -mlx5_glue_dv_create_flow_action_meter(struct mlx5dv_dr_flow_meter_attr *attr) -{ -#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) - return mlx5dv_dr_action_create_flow_meter(attr); -#else - (void)attr; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dv_modify_flow_action_meter(void *action, - struct mlx5dv_dr_flow_meter_attr *attr, - uint64_t modify_bits) -{ -#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) - return mlx5dv_dr_action_modify_flow_meter(action, attr, modify_bits); -#else - (void)action; - (void)attr; - (void)modify_bits; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_dv_destroy_flow(void *flow_id) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_rule_destroy(flow_id); -#else - return ibv_destroy_flow(flow_id); -#endif -} - -static int -mlx5_glue_dv_destroy_flow_matcher(void *matcher) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_matcher_destroy(matcher); -#else - return mlx5dv_destroy_flow_matcher(matcher); -#endif -#else - (void)matcher; - errno = ENOTSUP; - return errno; -#endif -} - -static struct ibv_context * -mlx5_glue_dv_open_device(struct ibv_device *device) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_open_device(device, - &(struct mlx5dv_context_attr){ - .flags = MLX5DV_CONTEXT_FLAGS_DEVX, - }); -#else - (void)device; - errno = ENOTSUP; - return NULL; -#endif -} - -static struct mlx5dv_devx_obj * -mlx5_glue_devx_obj_create(struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_create(ctx, in, inlen, out, outlen); -#else - (void)ctx; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_devx_obj_destroy(struct mlx5dv_devx_obj *obj) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_destroy(obj); -#else - (void)obj; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_query(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_query(obj, in, inlen, out, outlen); -#else - (void)obj; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_modify(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_modify(obj, in, inlen, out, outlen); -#else - (void)obj; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_general_cmd(struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_general_cmd(ctx, in, inlen, out, outlen); -#else - (void)ctx; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static struct mlx5dv_devx_cmd_comp * -mlx5_glue_devx_create_cmd_comp(struct ibv_context *ctx) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_create_cmd_comp(ctx); -#else - (void)ctx; - errno = -ENOTSUP; - return NULL; -#endif -} - -static void -mlx5_glue_devx_destroy_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - mlx5dv_devx_destroy_cmd_comp(cmd_comp); -#else - (void)cmd_comp; - errno = -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_query_async(struct mlx5dv_devx_obj *obj, const void *in, - size_t inlen, size_t outlen, uint64_t wr_id, - struct mlx5dv_devx_cmd_comp *cmd_comp) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_obj_query_async(obj, in, inlen, outlen, wr_id, - cmd_comp); -#else - (void)obj; - (void)in; - (void)inlen; - (void)outlen; - (void)wr_id; - (void)cmd_comp; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_get_async_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp, - struct mlx5dv_devx_async_cmd_hdr *cmd_resp, - size_t cmd_resp_len) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_get_async_cmd_comp(cmd_comp, cmd_resp, - cmd_resp_len); -#else - (void)cmd_comp; - (void)cmd_resp; - (void)cmd_resp_len; - return -ENOTSUP; -#endif -} - -static struct mlx5dv_devx_umem * -mlx5_glue_devx_umem_reg(struct ibv_context *context, void *addr, size_t size, - uint32_t access) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_umem_reg(context, addr, size, access); -#else - (void)context; - (void)addr; - (void)size; - (void)access; - errno = -ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_umem_dereg(dv_devx_umem); -#else - (void)dv_devx_umem; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_qp_query(struct ibv_qp *qp, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_QP - return mlx5dv_devx_qp_query(qp, in, inlen, out, outlen); -#else - (void)qp; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_devx_port_query(struct ibv_context *ctx, - uint32_t port_num, - struct mlx5dv_devx_port *mlx5_devx_port) -{ -#ifdef HAVE_MLX5DV_DR_DEVX_PORT - return mlx5dv_query_devx_port(ctx, port_num, mlx5_devx_port); -#else - (void)ctx; - (void)port_num; - (void)mlx5_devx_port; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_dr_dump_domain(FILE *file, void *domain) -{ -#ifdef HAVE_MLX5_DR_FLOW_DUMP - return mlx5dv_dump_dr_domain(file, domain); -#else - RTE_SET_USED(file); - RTE_SET_USED(domain); - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_query_eqn(struct ibv_context *ctx, uint32_t cpus, - uint32_t *eqn) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_query_eqn(ctx, cpus, eqn); -#else - (void)ctx; - (void)cpus; - (void)eqn; - return -ENOTSUP; -#endif -} - -static struct mlx5dv_devx_event_channel * -mlx5_glue_devx_create_event_channel(struct ibv_context *ctx, int flags) -{ -#ifdef HAVE_IBV_DEVX_EVENT - return mlx5dv_devx_create_event_channel(ctx, flags); -#else - (void)ctx; - (void)flags; - errno = ENOTSUP; - return NULL; -#endif -} - -static void -mlx5_glue_devx_destroy_event_channel(struct mlx5dv_devx_event_channel *eventc) -{ -#ifdef HAVE_IBV_DEVX_EVENT - mlx5dv_devx_destroy_event_channel(eventc); -#else - (void)eventc; -#endif -} - -static int -mlx5_glue_devx_subscribe_devx_event(struct mlx5dv_devx_event_channel *eventc, - struct mlx5dv_devx_obj *obj, - uint16_t events_sz, uint16_t events_num[], - uint64_t cookie) -{ -#ifdef HAVE_IBV_DEVX_EVENT - return mlx5dv_devx_subscribe_devx_event(eventc, obj, events_sz, - events_num, cookie); -#else - (void)eventc; - (void)obj; - (void)events_sz; - (void)events_num; - (void)cookie; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_subscribe_devx_event_fd(struct mlx5dv_devx_event_channel *eventc, - int fd, struct mlx5dv_devx_obj *obj, - uint16_t event_num) -{ -#ifdef HAVE_IBV_DEVX_EVENT - return mlx5dv_devx_subscribe_devx_event_fd(eventc, fd, obj, event_num); -#else - (void)eventc; - (void)fd; - (void)obj; - (void)event_num; - return -ENOTSUP; -#endif -} - -static ssize_t -mlx5_glue_devx_get_event(struct mlx5dv_devx_event_channel *eventc, - struct mlx5dv_devx_async_event_hdr *event_data, - size_t event_resp_len) -{ -#ifdef HAVE_IBV_DEVX_EVENT - return mlx5dv_devx_get_event(eventc, event_data, event_resp_len); -#else - (void)eventc; - (void)event_data; - (void)event_resp_len; - errno = ENOTSUP; - return -1; -#endif -} - -static struct mlx5dv_devx_uar * -mlx5_glue_devx_alloc_uar(struct ibv_context *context, uint32_t flags) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_alloc_uar(context, flags); -#else - (void)context; - (void)flags; - errno = ENOTSUP; - return NULL; -#endif -} - -static void -mlx5_glue_devx_free_uar(struct mlx5dv_devx_uar *devx_uar) -{ -#ifdef HAVE_IBV_DEVX_OBJ - mlx5dv_devx_free_uar(devx_uar); -#else - (void)devx_uar; -#endif -} - -static struct mlx5dv_var * -mlx5_glue_dv_alloc_var(struct ibv_context *context, uint32_t flags) -{ -#ifdef HAVE_IBV_VAR - return mlx5dv_alloc_var(context, flags); -#else - (void)context; - (void)flags; - errno = ENOTSUP; - return NULL; -#endif -} - -static void -mlx5_glue_dv_free_var(struct mlx5dv_var *var) -{ -#ifdef HAVE_IBV_VAR - mlx5dv_free_var(var); -#else - (void)var; - errno = ENOTSUP; -#endif -} - -__rte_cache_aligned -const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue) { - .version = MLX5_GLUE_VERSION, - .fork_init = mlx5_glue_fork_init, - .alloc_pd = mlx5_glue_alloc_pd, - .dealloc_pd = mlx5_glue_dealloc_pd, - .get_device_list = mlx5_glue_get_device_list, - .free_device_list = mlx5_glue_free_device_list, - .open_device = mlx5_glue_open_device, - .close_device = mlx5_glue_close_device, - .query_device = mlx5_glue_query_device, - .query_device_ex = mlx5_glue_query_device_ex, - .query_rt_values_ex = mlx5_glue_query_rt_values_ex, - .query_port = mlx5_glue_query_port, - .create_comp_channel = mlx5_glue_create_comp_channel, - .destroy_comp_channel = mlx5_glue_destroy_comp_channel, - .create_cq = mlx5_glue_create_cq, - .destroy_cq = mlx5_glue_destroy_cq, - .get_cq_event = mlx5_glue_get_cq_event, - .ack_cq_events = mlx5_glue_ack_cq_events, - .create_rwq_ind_table = mlx5_glue_create_rwq_ind_table, - .destroy_rwq_ind_table = mlx5_glue_destroy_rwq_ind_table, - .create_wq = mlx5_glue_create_wq, - .destroy_wq = mlx5_glue_destroy_wq, - .modify_wq = mlx5_glue_modify_wq, - .create_flow = mlx5_glue_create_flow, - .destroy_flow = mlx5_glue_destroy_flow, - .destroy_flow_action = mlx5_glue_destroy_flow_action, - .create_qp = mlx5_glue_create_qp, - .create_qp_ex = mlx5_glue_create_qp_ex, - .destroy_qp = mlx5_glue_destroy_qp, - .modify_qp = mlx5_glue_modify_qp, - .reg_mr = mlx5_glue_reg_mr, - .alloc_null_mr = mlx5_glue_alloc_null_mr, - .dereg_mr = mlx5_glue_dereg_mr, - .create_counter_set = mlx5_glue_create_counter_set, - .destroy_counter_set = mlx5_glue_destroy_counter_set, - .describe_counter_set = mlx5_glue_describe_counter_set, - .query_counter_set = mlx5_glue_query_counter_set, - .create_counters = mlx5_glue_create_counters, - .destroy_counters = mlx5_glue_destroy_counters, - .attach_counters = mlx5_glue_attach_counters, - .query_counters = mlx5_glue_query_counters, - .ack_async_event = mlx5_glue_ack_async_event, - .get_async_event = mlx5_glue_get_async_event, - .port_state_str = mlx5_glue_port_state_str, - .cq_ex_to_cq = mlx5_glue_cq_ex_to_cq, - .dr_create_flow_action_dest_flow_tbl = - mlx5_glue_dr_create_flow_action_dest_flow_tbl, - .dr_create_flow_action_dest_port = - mlx5_glue_dr_create_flow_action_dest_port, - .dr_create_flow_action_drop = - mlx5_glue_dr_create_flow_action_drop, - .dr_create_flow_action_push_vlan = - mlx5_glue_dr_create_flow_action_push_vlan, - .dr_create_flow_action_pop_vlan = - mlx5_glue_dr_create_flow_action_pop_vlan, - .dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl, - .dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl, - .dr_create_domain = mlx5_glue_dr_create_domain, - .dr_destroy_domain = mlx5_glue_dr_destroy_domain, - .dv_create_cq = mlx5_glue_dv_create_cq, - .dv_create_wq = mlx5_glue_dv_create_wq, - .dv_query_device = mlx5_glue_dv_query_device, - .dv_set_context_attr = mlx5_glue_dv_set_context_attr, - .dv_init_obj = mlx5_glue_dv_init_obj, - .dv_create_qp = mlx5_glue_dv_create_qp, - .dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher, - .dv_create_flow = mlx5_glue_dv_create_flow, - .dv_create_flow_action_counter = - mlx5_glue_dv_create_flow_action_counter, - .dv_create_flow_action_dest_ibv_qp = - mlx5_glue_dv_create_flow_action_dest_ibv_qp, - .dv_create_flow_action_dest_devx_tir = - mlx5_glue_dv_create_flow_action_dest_devx_tir, - .dv_create_flow_action_modify_header = - mlx5_glue_dv_create_flow_action_modify_header, - .dv_create_flow_action_packet_reformat = - mlx5_glue_dv_create_flow_action_packet_reformat, - .dv_create_flow_action_tag = mlx5_glue_dv_create_flow_action_tag, - .dv_create_flow_action_meter = mlx5_glue_dv_create_flow_action_meter, - .dv_modify_flow_action_meter = mlx5_glue_dv_modify_flow_action_meter, - .dv_destroy_flow = mlx5_glue_dv_destroy_flow, - .dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher, - .dv_open_device = mlx5_glue_dv_open_device, - .devx_obj_create = mlx5_glue_devx_obj_create, - .devx_obj_destroy = mlx5_glue_devx_obj_destroy, - .devx_obj_query = mlx5_glue_devx_obj_query, - .devx_obj_modify = mlx5_glue_devx_obj_modify, - .devx_general_cmd = mlx5_glue_devx_general_cmd, - .devx_create_cmd_comp = mlx5_glue_devx_create_cmd_comp, - .devx_destroy_cmd_comp = mlx5_glue_devx_destroy_cmd_comp, - .devx_obj_query_async = mlx5_glue_devx_obj_query_async, - .devx_get_async_cmd_comp = mlx5_glue_devx_get_async_cmd_comp, - .devx_umem_reg = mlx5_glue_devx_umem_reg, - .devx_umem_dereg = mlx5_glue_devx_umem_dereg, - .devx_qp_query = mlx5_glue_devx_qp_query, - .devx_port_query = mlx5_glue_devx_port_query, - .dr_dump_domain = mlx5_glue_dr_dump_domain, - .devx_query_eqn = mlx5_glue_devx_query_eqn, - .devx_create_event_channel = mlx5_glue_devx_create_event_channel, - .devx_destroy_event_channel = mlx5_glue_devx_destroy_event_channel, - .devx_subscribe_devx_event = mlx5_glue_devx_subscribe_devx_event, - .devx_subscribe_devx_event_fd = mlx5_glue_devx_subscribe_devx_event_fd, - .devx_get_event = mlx5_glue_devx_get_event, - .devx_alloc_uar = mlx5_glue_devx_alloc_uar, - .devx_free_uar = mlx5_glue_devx_free_uar, - .dv_alloc_var = mlx5_glue_dv_alloc_var, - .dv_free_var = mlx5_glue_dv_free_var, -}; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h deleted file mode 100644 index 81d6a22..0000000 --- a/drivers/common/mlx5/mlx5_glue.h +++ /dev/null @@ -1,309 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#ifndef MLX5_GLUE_H_ -#define MLX5_GLUE_H_ - -#include -#include -/* Verbs headers do not support -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -#include -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - -#include - -#include "mlx5_autoconf.h" - -#ifndef MLX5_GLUE_VERSION -#define MLX5_GLUE_VERSION "" -#endif - -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 -struct ibv_counter_set; -struct ibv_counter_set_data; -struct ibv_counter_set_description; -struct ibv_counter_set_init_attr; -struct ibv_query_counter_set_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 -struct ibv_counters; -struct ibv_counters_init_attr; -struct ibv_counter_attach_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_TUNNEL_SUPPORT -struct mlx5dv_qp_init_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT -struct mlx5dv_wq_init_attr; -#endif - -#ifndef HAVE_IBV_FLOW_DV_SUPPORT -struct mlx5dv_flow_matcher; -struct mlx5dv_flow_matcher_attr; -struct mlx5dv_flow_action_attr; -struct mlx5dv_flow_match_parameters; -struct mlx5dv_dr_flow_meter_attr; -struct ibv_flow_action; -enum mlx5dv_flow_action_packet_reformat_type { packet_reformat_type = 0, }; -enum mlx5dv_flow_table_type { flow_table_type = 0, }; -#endif - -#ifndef HAVE_IBV_FLOW_DEVX_COUNTERS -#define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0 -#endif - -#ifndef HAVE_IBV_DEVX_OBJ -struct mlx5dv_devx_obj; -struct mlx5dv_devx_umem { uint32_t umem_id; }; -struct mlx5dv_devx_uar { void *reg_addr; void *base_addr; uint32_t page_id; }; -#endif - -#ifndef HAVE_IBV_DEVX_ASYNC -struct mlx5dv_devx_cmd_comp; -struct mlx5dv_devx_async_cmd_hdr; -#endif - -#ifndef HAVE_MLX5DV_DR -enum mlx5dv_dr_domain_type { unused, }; -struct mlx5dv_dr_domain; -#endif - -#ifndef HAVE_MLX5DV_DR_DEVX_PORT -struct mlx5dv_devx_port; -#endif - -#ifndef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER -struct mlx5dv_dr_flow_meter_attr; -#endif - -#ifndef HAVE_IBV_DEVX_EVENT -struct mlx5dv_devx_event_channel { int fd; }; -struct mlx5dv_devx_async_event_hdr; -#define MLX5DV_DEVX_CREATE_EVENT_CHANNEL_FLAGS_OMIT_EV_DATA 1 -#endif - -#ifndef HAVE_IBV_VAR -struct mlx5dv_var { uint32_t page_id; uint32_t length; off_t mmap_off; - uint64_t comp_mask; }; -#endif - -#ifndef HAVE_IBV_RELAXED_ORDERING -#define IBV_ACCESS_RELAXED_ORDERING 0 -#endif - -/* LIB_GLUE_VERSION must be updated every time this structure is modified. */ -struct mlx5_glue { - const char *version; - int (*fork_init)(void); - struct ibv_pd *(*alloc_pd)(struct ibv_context *context); - int (*dealloc_pd)(struct ibv_pd *pd); - struct ibv_device **(*get_device_list)(int *num_devices); - void (*free_device_list)(struct ibv_device **list); - struct ibv_context *(*open_device)(struct ibv_device *device); - int (*close_device)(struct ibv_context *context); - int (*query_device)(struct ibv_context *context, - struct ibv_device_attr *device_attr); - int (*query_device_ex)(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr); - int (*query_rt_values_ex)(struct ibv_context *context, - struct ibv_values_ex *values); - int (*query_port)(struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr); - struct ibv_comp_channel *(*create_comp_channel) - (struct ibv_context *context); - int (*destroy_comp_channel)(struct ibv_comp_channel *channel); - struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, - void *cq_context, - struct ibv_comp_channel *channel, - int comp_vector); - int (*destroy_cq)(struct ibv_cq *cq); - int (*get_cq_event)(struct ibv_comp_channel *channel, - struct ibv_cq **cq, void **cq_context); - void (*ack_cq_events)(struct ibv_cq *cq, unsigned int nevents); - struct ibv_rwq_ind_table *(*create_rwq_ind_table) - (struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr); - int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); - struct ibv_wq *(*create_wq)(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr); - int (*destroy_wq)(struct ibv_wq *wq); - int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); - struct ibv_flow *(*create_flow)(struct ibv_qp *qp, - struct ibv_flow_attr *flow); - int (*destroy_flow)(struct ibv_flow *flow_id); - int (*destroy_flow_action)(void *action); - struct ibv_qp *(*create_qp)(struct ibv_pd *pd, - struct ibv_qp_init_attr *qp_init_attr); - struct ibv_qp *(*create_qp_ex) - (struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex); - int (*destroy_qp)(struct ibv_qp *qp); - int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask); - struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, - size_t length, int access); - struct ibv_mr *(*alloc_null_mr)(struct ibv_pd *pd); - int (*dereg_mr)(struct ibv_mr *mr); - struct ibv_counter_set *(*create_counter_set) - (struct ibv_context *context, - struct ibv_counter_set_init_attr *init_attr); - int (*destroy_counter_set)(struct ibv_counter_set *cs); - int (*describe_counter_set) - (struct ibv_context *context, - uint16_t counter_set_id, - struct ibv_counter_set_description *cs_desc); - int (*query_counter_set)(struct ibv_query_counter_set_attr *query_attr, - struct ibv_counter_set_data *cs_data); - struct ibv_counters *(*create_counters) - (struct ibv_context *context, - struct ibv_counters_init_attr *init_attr); - int (*destroy_counters)(struct ibv_counters *counters); - int (*attach_counters)(struct ibv_counters *counters, - struct ibv_counter_attach_attr *attr, - struct ibv_flow *flow); - int (*query_counters)(struct ibv_counters *counters, - uint64_t *counters_value, - uint32_t ncounters, - uint32_t flags); - void (*ack_async_event)(struct ibv_async_event *event); - int (*get_async_event)(struct ibv_context *context, - struct ibv_async_event *event); - const char *(*port_state_str)(enum ibv_port_state port_state); - struct ibv_cq *(*cq_ex_to_cq)(struct ibv_cq_ex *cq); - void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); - void *(*dr_create_flow_action_dest_port)(void *domain, - uint32_t port); - void *(*dr_create_flow_action_drop)(); - void *(*dr_create_flow_action_push_vlan) - (struct mlx5dv_dr_domain *domain, - rte_be32_t vlan_tag); - void *(*dr_create_flow_action_pop_vlan)(); - void *(*dr_create_flow_tbl)(void *domain, uint32_t level); - int (*dr_destroy_flow_tbl)(void *tbl); - void *(*dr_create_domain)(struct ibv_context *ctx, - enum mlx5dv_dr_domain_type domain); - int (*dr_destroy_domain)(void *domain); - struct ibv_cq_ex *(*dv_create_cq) - (struct ibv_context *context, - struct ibv_cq_init_attr_ex *cq_attr, - struct mlx5dv_cq_init_attr *mlx5_cq_attr); - struct ibv_wq *(*dv_create_wq) - (struct ibv_context *context, - struct ibv_wq_init_attr *wq_attr, - struct mlx5dv_wq_init_attr *mlx5_wq_attr); - int (*dv_query_device)(struct ibv_context *ctx_in, - struct mlx5dv_context *attrs_out); - int (*dv_set_context_attr)(struct ibv_context *ibv_ctx, - enum mlx5dv_set_ctx_attr_type type, - void *attr); - int (*dv_init_obj)(struct mlx5dv_obj *obj, uint64_t obj_type); - struct ibv_qp *(*dv_create_qp) - (struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex, - struct mlx5dv_qp_init_attr *dv_qp_init_attr); - void *(*dv_create_flow_matcher) - (struct ibv_context *context, - struct mlx5dv_flow_matcher_attr *matcher_attr, - void *tbl); - void *(*dv_create_flow)(void *matcher, void *match_value, - size_t num_actions, void *actions[]); - void *(*dv_create_flow_action_counter)(void *obj, uint32_t offset); - void *(*dv_create_flow_action_dest_ibv_qp)(void *qp); - void *(*dv_create_flow_action_dest_devx_tir)(void *tir); - void *(*dv_create_flow_action_modify_header) - (struct ibv_context *ctx, enum mlx5dv_flow_table_type ft_type, - void *domain, uint64_t flags, size_t actions_sz, - uint64_t actions[]); - void *(*dv_create_flow_action_packet_reformat) - (struct ibv_context *ctx, - enum mlx5dv_flow_action_packet_reformat_type reformat_type, - enum mlx5dv_flow_table_type ft_type, - struct mlx5dv_dr_domain *domain, - uint32_t flags, size_t data_sz, void *data); - void *(*dv_create_flow_action_tag)(uint32_t tag); - void *(*dv_create_flow_action_meter) - (struct mlx5dv_dr_flow_meter_attr *attr); - int (*dv_modify_flow_action_meter)(void *action, - struct mlx5dv_dr_flow_meter_attr *attr, uint64_t modify_bits); - int (*dv_destroy_flow)(void *flow); - int (*dv_destroy_flow_matcher)(void *matcher); - struct ibv_context *(*dv_open_device)(struct ibv_device *device); - struct mlx5dv_var *(*dv_alloc_var)(struct ibv_context *context, - uint32_t flags); - void (*dv_free_var)(struct mlx5dv_var *var); - struct mlx5dv_devx_uar *(*devx_alloc_uar)(struct ibv_context *context, - uint32_t flags); - void (*devx_free_uar)(struct mlx5dv_devx_uar *devx_uar); - struct mlx5dv_devx_obj *(*devx_obj_create) - (struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_obj_destroy)(struct mlx5dv_devx_obj *obj); - int (*devx_obj_query)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_obj_modify)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_general_cmd)(struct ibv_context *context, - const void *in, size_t inlen, - void *out, size_t outlen); - struct mlx5dv_devx_cmd_comp *(*devx_create_cmd_comp) - (struct ibv_context *context); - void (*devx_destroy_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp); - int (*devx_obj_query_async)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - size_t outlen, uint64_t wr_id, - struct mlx5dv_devx_cmd_comp *cmd_comp); - int (*devx_get_async_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp, - struct mlx5dv_devx_async_cmd_hdr *resp, - size_t cmd_resp_len); - struct mlx5dv_devx_umem *(*devx_umem_reg)(struct ibv_context *context, - void *addr, size_t size, - uint32_t access); - int (*devx_umem_dereg)(struct mlx5dv_devx_umem *dv_devx_umem); - int (*devx_qp_query)(struct ibv_qp *qp, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_port_query)(struct ibv_context *ctx, - uint32_t port_num, - struct mlx5dv_devx_port *mlx5_devx_port); - int (*dr_dump_domain)(FILE *file, void *domain); - int (*devx_query_eqn)(struct ibv_context *context, uint32_t cpus, - uint32_t *eqn); - struct mlx5dv_devx_event_channel *(*devx_create_event_channel) - (struct ibv_context *context, int flags); - void (*devx_destroy_event_channel) - (struct mlx5dv_devx_event_channel *event_channel); - int (*devx_subscribe_devx_event) - (struct mlx5dv_devx_event_channel *event_channel, - struct mlx5dv_devx_obj *obj, - uint16_t events_sz, - uint16_t events_num[], - uint64_t cookie); - int (*devx_subscribe_devx_event_fd) - (struct mlx5dv_devx_event_channel *event_channel, - int fd, - struct mlx5dv_devx_obj *obj, - uint16_t event_num); - ssize_t (*devx_get_event) - (struct mlx5dv_devx_event_channel *event_channel, - struct mlx5dv_devx_async_event_hdr *event_data, - size_t event_resp_len); -}; - -extern const struct mlx5_glue *mlx5_glue; - -#endif /* MLX5_GLUE_H_ */ diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 2577ee5..c160e6b 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -38,6 +38,7 @@ CFLAGS += -O3 CFLAGS += -std=c11 -Wall -Wextra CFLAGS += -g CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5 +CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5/linux CFLAGS += -I$(RTE_SDK)/drivers/net/mlx5 CFLAGS += -I$(BUILDDIR)/drivers/common/mlx5 CFLAGS += -D_BSD_SOURCE diff --git a/drivers/vdpa/mlx5/Makefile b/drivers/vdpa/mlx5/Makefile index ef34c0b..91c89d6 100644 --- a/drivers/vdpa/mlx5/Makefile +++ b/drivers/vdpa/mlx5/Makefile @@ -20,6 +20,7 @@ CFLAGS += -O3 CFLAGS += -std=c11 -Wall -Wextra CFLAGS += -g CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5 +CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5/linux CFLAGS += -I$(RTE_SDK)/drivers/net/mlx5_vdpa CFLAGS += -I$(RTE_SDK)/lib/librte_sched CFLAGS += -I$(BUILDDIR)/drivers/common/mlx5 From patchwork Wed May 27 16:14:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ophir Munk X-Patchwork-Id: 70660 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 24904A0093; Wed, 27 May 2020 18:15:12 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 51E7A1D98A; Wed, 27 May 2020 18:14:48 +0200 (CEST) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70075.outbound.protection.outlook.com [40.107.7.75]) by dpdk.org (Postfix) with ESMTP id 98C0C1D420 for ; Wed, 27 May 2020 18:14:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Rf9t/XCuQzJhc71AY446IThU06uMJ/0Y8aioEZhjFOBAkEBuk9t87wFlelzYu6bZOQhWFGTpQ37AGltil8GV7sMZhMrWVsseu1qoTdBUQoSpCIbPne5CKi6ocprDopwsEETihYDexXIhWZ4TnENbOiXiIreZmbPuk+GdMFvbtvrXtMToyJ1DKPGMYvRQGoLZadfyMdGkCVvuUildGVtZ74PeoH5xCRFplNUhKTFdJ4zoxOFjOxa9Zw5IMZZys9gxotcmW8RHQm9ckGqcJczdA7XnDUNmsvqe2O7fL4Ip7X7PPcvk0EqY2aocPUYMt42Hsw06rubqRiHljCVwitVzhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=eyK0kT2GkznlHEufPENK8iBDYWmRmEUNkPNJHZ1/7Cg=; b=hF+V/f0LWURVJXCXpCjPBQHedZBsTIoNXBtR4cCXBqCbzaAr/GdDocdL57rH5De8mJFW4dNdMwq85/4jM17mW5Wu9XOi0obpdmvrGwYJVZli+I619FHqXfA7Ck5q4+qYQNwbBLWSQ0Wl2kDEuCOfANORK9y+lw/NUHHCksiohaY4lZX/n+B+kUp92U1QFaRc08YBCBdnDcXVVBa7GpPuLcLZJl/3rVBZX4mzjCaZIxEV6OrWbPkrHEj55GGEswyLhhNFyn0LrSkkmGmX9A3+G1HfPBeqyuYZxpvUndxAxM/McxtFwOqWOvAl+HslCzXaA5nLtqEPL+n9PWsaMSRlmA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=eyK0kT2GkznlHEufPENK8iBDYWmRmEUNkPNJHZ1/7Cg=; b=CyCeeXIzNoS87pq52iVFHfITRYHeHtO55/ddCMBVU4QCimAIs6sqXZS88YH/Z7xPdVcse12dxkbpLdaVwC4T0GdO5Vp0brzwyB8GxPys7E6llE0vh4nAm/CFaMpHyb5bwF9bHgJyJT4GyIBCKYOIRAm0jTOWwxGdg1aO/+r2k8Q= Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=mellanox.com; Received: from AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) by AM0PR05MB4497.eurprd05.prod.outlook.com (2603:10a6:208:67::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.24; Wed, 27 May 2020 16:14:41 +0000 Received: from AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a]) by AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a%3]) with mapi id 15.20.3021.029; Wed, 27 May 2020 16:14:41 +0000 From: Ophir Munk To: dev@dpdk.org, Matan Azrad Cc: Ophir Munk Date: Wed, 27 May 2020 16:14:24 +0000 Message-Id: <20200527161425.22944-2-ophirmu@mellanox.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20200527161425.22944-1-ophirmu@mellanox.com> References: <20200527161425.22944-1-ophirmu@mellanox.com> X-ClientProxiedBy: AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) To AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from mellanox.com (37.142.13.130) by AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.18 via Frontend Transport; Wed, 27 May 2020 16:14:40 +0000 X-Mailer: git-send-email 2.8.4 X-Originating-IP: [37.142.13.130] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 716e9bfc-283d-4c57-afb8-08d802590f59 X-MS-TrafficTypeDiagnostic: AM0PR05MB4497: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:327; X-Forefront-PRVS: 04163EF38A X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: jVm+RKBr2S4Jyi3I3QHQ+4dgk8tCoW45vxitfjVLVvr+ZrCRTTTZ4AAHBI84FSaILWSS2Ll6H6nhg4VjZzPhISbMw3vBAtCmFjY0Iu8a598FSjnXpsKJWjMFts6DZC25CPxj+RGDah+Xs3Fhognz26bnxGfEJTH53+RjP5Irifcr9gsFen+XGtcOESc44FVYs15mPznx1e8bg7dDRmBaWcs9stFza+Trf+Hf1K2n+G1dlkUb+7wFExdkhk9LtGc3XJ8bSDCRpeJRDCz/3uPyB+7L3c2+zAcxMpgy/28XpzmSZgCoYgHdEdGDcUvZieGV3Nlk7MON/k0kOOh0Z2VBYA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM0PR05MB4209.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(39860400002)(376002)(346002)(396003)(366004)(136003)(2906002)(6636002)(7696005)(8886007)(1076003)(26005)(8676002)(5660300002)(37006003)(52116002)(36756003)(186003)(16526019)(30864003)(6666004)(83380400001)(8936002)(316002)(478600001)(66946007)(66556008)(86362001)(2616005)(956004)(66476007)(6862004)(107886003)(4326008)(55016002)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: fqiuLpTMEio4gKr3iuu2yXeYyeXKxNjsI6zLXuL8L9SsrMGc5HK7ZBOnWee9YJH3ekQs9jBlVFn6lxfHY6q3bYVYZkyC9PXarhOrM808jqNzPeAP+ZkoBnmXKdffPmFD9b5sCzVDLlwB71HpmZd1HJe0lZXW9s0EgIV+CM9aqOVpnKOcAkEGKBhknH31ly02/bRA6sYynPVTlcm01sPsGGEmpiXXL/WCeRgHke7PL0RBOGfXhjGve0/JNpTpJ5YhYZMr/ieKNhabu4zAV0TpcZbkK5YG3bbcQalaz2ABxVKbyogazdlcxQXkjDepg49fGTnpZ2MQbQEkcrX9HIweQEgppUl1ftMtlwjcRria+eD4h5q6oTPfSNrYFAX4Wx9Iya1GEtspQwv60yVduUGZIG8LZntOv9HTJB/DWbx6qjTrbHz+xOmTwZFAqcAfeWQ81eACz3dIMzuUYCFljkNNPb/WxYU+PzZ2QsoqSOSGSWI= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 716e9bfc-283d-4c57-afb8-08d802590f59 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 May 2020 16:14:40.9533 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: cClClY7gk/yfxv9ZCHu/VT+75pp5AnvVY/VcJRVD6emfvqxDis4n8xyW5Bnw21uzquFr6r56G6srTA0D8gdoug== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4497 Subject: [dpdk-dev] [PATCH v1 2/3] common/mlx5: move netlink files under Linux directory X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" File mlx5_nl.c is using Netlink APIs which are Linux specifics. Move it (including file mlx5_nl.h) to common/mlx5/linux directory. Signed-off-by: Ophir Munk --- drivers/common/mlx5/Makefile | 2 +- drivers/common/mlx5/linux/meson.build | 1 + drivers/common/mlx5/linux/mlx5_nl.c | 1721 +++++++++++++++++++++++++++++++++ drivers/common/mlx5/linux/mlx5_nl.h | 79 ++ drivers/common/mlx5/meson.build | 1 - drivers/common/mlx5/mlx5_nl.c | 1721 --------------------------------- drivers/common/mlx5/mlx5_nl.h | 79 -- 7 files changed, 1802 insertions(+), 1802 deletions(-) create mode 100644 drivers/common/mlx5/linux/mlx5_nl.c create mode 100644 drivers/common/mlx5/linux/mlx5_nl.h delete mode 100644 drivers/common/mlx5/mlx5_nl.c delete mode 100644 drivers/common/mlx5/mlx5_nl.h diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 19b1466..40bf2a5 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -16,7 +16,7 @@ SRCS-y += linux/mlx5_glue.c endif SRCS-y += mlx5_devx_cmds.c SRCS-y += mlx5_common.c -SRCS-y += mlx5_nl.c +SRCS-y += linux/mlx5_nl.c SRCS-y += mlx5_common_mp.c SRCS-y += mlx5_common_mr.c ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) diff --git a/drivers/common/mlx5/linux/meson.build b/drivers/common/mlx5/linux/meson.build index a123fd6..04f7e03 100644 --- a/drivers/common/mlx5/linux/meson.build +++ b/drivers/common/mlx5/linux/meson.build @@ -45,6 +45,7 @@ if static_ibverbs ext_deps += declare_dependency(link_args:ibv_ldflags.split()) endif +sources += files('mlx5_nl.c') if not dlopen_ibverbs sources += files('mlx5_glue.c') endif diff --git a/drivers/common/mlx5/linux/mlx5_nl.c b/drivers/common/mlx5/linux/mlx5_nl.c new file mode 100644 index 0000000..1a1033a --- /dev/null +++ b/drivers/common/mlx5/linux/mlx5_nl.c @@ -0,0 +1,1721 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mlx5_nl.h" +#include "mlx5_common_utils.h" +#ifdef HAVE_DEVLINK +#include +#endif + + +/* Size of the buffer to receive kernel messages */ +#define MLX5_NL_BUF_SIZE (32 * 1024) +/* Send buffer size for the Netlink socket */ +#define MLX5_SEND_BUF_SIZE 32768 +/* Receive buffer size for the Netlink socket */ +#define MLX5_RECV_BUF_SIZE 32768 + +/** Parameters of VLAN devices created by driver. */ +#define MLX5_VMWA_VLAN_DEVICE_PFX "evmlx" +/* + * Define NDA_RTA as defined in iproute2 sources. + * + * see in iproute2 sources file include/libnetlink.h + */ +#ifndef MLX5_NDA_RTA +#define MLX5_NDA_RTA(r) \ + ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif +/* + * Define NLMSG_TAIL as defined in iproute2 sources. + * + * see in iproute2 sources file include/libnetlink.h + */ +#ifndef NLMSG_TAIL +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *)(((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#endif +/* + * The following definitions are normally found in rdma/rdma_netlink.h, + * however they are so recent that most systems do not expose them yet. + */ +#ifndef HAVE_RDMA_NL_NLDEV +#define RDMA_NL_NLDEV 5 +#endif +#ifndef HAVE_RDMA_NLDEV_CMD_GET +#define RDMA_NLDEV_CMD_GET 1 +#endif +#ifndef HAVE_RDMA_NLDEV_CMD_PORT_GET +#define RDMA_NLDEV_CMD_PORT_GET 5 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_INDEX +#define RDMA_NLDEV_ATTR_DEV_INDEX 1 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_NAME +#define RDMA_NLDEV_ATTR_DEV_NAME 2 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_PORT_INDEX +#define RDMA_NLDEV_ATTR_PORT_INDEX 3 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX +#define RDMA_NLDEV_ATTR_NDEV_INDEX 50 +#endif + +/* These are normally found in linux/if_link.h. */ +#ifndef HAVE_IFLA_NUM_VF +#define IFLA_NUM_VF 21 +#endif +#ifndef HAVE_IFLA_EXT_MASK +#define IFLA_EXT_MASK 29 +#endif +#ifndef HAVE_IFLA_PHYS_SWITCH_ID +#define IFLA_PHYS_SWITCH_ID 36 +#endif +#ifndef HAVE_IFLA_PHYS_PORT_NAME +#define IFLA_PHYS_PORT_NAME 38 +#endif + +/* + * Some Devlink defines may be missed in old kernel versions, + * adjust used defines. + */ +#ifndef DEVLINK_GENL_NAME +#define DEVLINK_GENL_NAME "devlink" +#endif +#ifndef DEVLINK_GENL_VERSION +#define DEVLINK_GENL_VERSION 1 +#endif +#ifndef DEVLINK_ATTR_BUS_NAME +#define DEVLINK_ATTR_BUS_NAME 1 +#endif +#ifndef DEVLINK_ATTR_DEV_NAME +#define DEVLINK_ATTR_DEV_NAME 2 +#endif +#ifndef DEVLINK_ATTR_PARAM +#define DEVLINK_ATTR_PARAM 80 +#endif +#ifndef DEVLINK_ATTR_PARAM_NAME +#define DEVLINK_ATTR_PARAM_NAME 81 +#endif +#ifndef DEVLINK_ATTR_PARAM_TYPE +#define DEVLINK_ATTR_PARAM_TYPE 83 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUES_LIST +#define DEVLINK_ATTR_PARAM_VALUES_LIST 84 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE +#define DEVLINK_ATTR_PARAM_VALUE 85 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE_DATA +#define DEVLINK_ATTR_PARAM_VALUE_DATA 86 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE_CMODE +#define DEVLINK_ATTR_PARAM_VALUE_CMODE 87 +#endif +#ifndef DEVLINK_PARAM_CMODE_DRIVERINIT +#define DEVLINK_PARAM_CMODE_DRIVERINIT 1 +#endif +#ifndef DEVLINK_CMD_RELOAD +#define DEVLINK_CMD_RELOAD 37 +#endif +#ifndef DEVLINK_CMD_PARAM_GET +#define DEVLINK_CMD_PARAM_GET 38 +#endif +#ifndef DEVLINK_CMD_PARAM_SET +#define DEVLINK_CMD_PARAM_SET 39 +#endif +#ifndef NLA_FLAG +#define NLA_FLAG 6 +#endif + +/* Add/remove MAC address through Netlink */ +struct mlx5_nl_mac_addr { + struct rte_ether_addr (*mac)[]; + /**< MAC address handled by the device. */ + int mac_n; /**< Number of addresses in the array. */ +}; + +#define MLX5_NL_CMD_GET_IB_NAME (1 << 0) +#define MLX5_NL_CMD_GET_IB_INDEX (1 << 1) +#define MLX5_NL_CMD_GET_NET_INDEX (1 << 2) +#define MLX5_NL_CMD_GET_PORT_INDEX (1 << 3) + +/** Data structure used by mlx5_nl_cmdget_cb(). */ +struct mlx5_nl_ifindex_data { + const char *name; /**< IB device name (in). */ + uint32_t flags; /**< found attribute flags (out). */ + uint32_t ibindex; /**< IB device index (out). */ + uint32_t ifindex; /**< Network interface index (out). */ + uint32_t portnum; /**< IB device max port number (out). */ +}; + +rte_atomic32_t atomic_sn = RTE_ATOMIC32_INIT(0); + +/* Generate Netlink sequence number. */ +#define MLX5_NL_SN_GENERATE ((uint32_t)rte_atomic32_add_return(&atomic_sn, 1)) + +/** + * Opens a Netlink socket. + * + * @param protocol + * Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA). + * + * @return + * A file descriptor on success, a negative errno value otherwise and + * rte_errno is set. + */ +int +mlx5_nl_init(int protocol) +{ + int fd; + int sndbuf_size = MLX5_SEND_BUF_SIZE; + int rcvbuf_size = MLX5_RECV_BUF_SIZE; + struct sockaddr_nl local = { + .nl_family = AF_NETLINK, + }; + int ret; + + fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); + if (fd == -1) { + rte_errno = errno; + return -rte_errno; + } + ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(int)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, sizeof(int)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + ret = bind(fd, (struct sockaddr *)&local, sizeof(local)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + return fd; +error: + close(fd); + return -rte_errno; +} + +/** + * Send a request message to the kernel on the Netlink socket. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] nh + * The Netlink message send to the kernel. + * @param[in] ssn + * Sequence number. + * @param[in] req + * Pointer to the request structure. + * @param[in] len + * Length of the request in bytes. + * + * @return + * The number of sent bytes on success, a negative errno value otherwise and + * rte_errno is set. + */ +static int +mlx5_nl_request(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn, void *req, + int len) +{ + struct sockaddr_nl sa = { + .nl_family = AF_NETLINK, + }; + struct iovec iov[2] = { + { .iov_base = nh, .iov_len = sizeof(*nh), }, + { .iov_base = req, .iov_len = len, }, + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = iov, + .msg_iovlen = 2, + }; + int send_bytes; + + nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ + nh->nlmsg_seq = sn; + send_bytes = sendmsg(nlsk_fd, &msg, 0); + if (send_bytes < 0) { + rte_errno = errno; + return -rte_errno; + } + return send_bytes; +} + +/** + * Send a message to the kernel on the Netlink socket. + * + * @param[in] nlsk_fd + * The Netlink socket file descriptor used for communication. + * @param[in] nh + * The Netlink message send to the kernel. + * @param[in] sn + * Sequence number. + * + * @return + * The number of sent bytes on success, a negative errno value otherwise and + * rte_errno is set. + */ +static int +mlx5_nl_send(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn) +{ + struct sockaddr_nl sa = { + .nl_family = AF_NETLINK, + }; + struct iovec iov = { + .iov_base = nh, + .iov_len = nh->nlmsg_len, + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + int send_bytes; + + nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ + nh->nlmsg_seq = sn; + send_bytes = sendmsg(nlsk_fd, &msg, 0); + if (send_bytes < 0) { + rte_errno = errno; + return -rte_errno; + } + return send_bytes; +} + +/** + * Receive a message from the kernel on the Netlink socket, following + * mlx5_nl_send(). + * + * @param[in] nlsk_fd + * The Netlink socket file descriptor used for communication. + * @param[in] sn + * Sequence number. + * @param[in] cb + * The callback function to call for each Netlink message received. + * @param[in, out] arg + * Custom arguments for the callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), + void *arg) +{ + struct sockaddr_nl sa; + void *buf = malloc(MLX5_RECV_BUF_SIZE); + struct iovec iov = { + .iov_base = buf, + .iov_len = MLX5_RECV_BUF_SIZE, + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + /* One message at a time */ + .msg_iovlen = 1, + }; + int multipart = 0; + int ret = 0; + + if (!buf) { + rte_errno = ENOMEM; + return -rte_errno; + } + do { + struct nlmsghdr *nh; + int recv_bytes = 0; + + do { + recv_bytes = recvmsg(nlsk_fd, &msg, 0); + if (recv_bytes == -1) { + rte_errno = errno; + ret = -rte_errno; + goto exit; + } + nh = (struct nlmsghdr *)buf; + } while (nh->nlmsg_seq != sn); + for (; + NLMSG_OK(nh, (unsigned int)recv_bytes); + nh = NLMSG_NEXT(nh, recv_bytes)) { + if (nh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err_data = NLMSG_DATA(nh); + + if (err_data->error < 0) { + rte_errno = -err_data->error; + ret = -rte_errno; + goto exit; + } + /* Ack message. */ + ret = 0; + goto exit; + } + /* Multi-part msgs and their trailing DONE message. */ + if (nh->nlmsg_flags & NLM_F_MULTI) { + if (nh->nlmsg_type == NLMSG_DONE) { + ret = 0; + goto exit; + } + multipart = 1; + } + if (cb) { + ret = cb(nh, arg); + if (ret < 0) + goto exit; + } + } + } while (multipart); +exit: + free(buf); + return ret; +} + +/** + * Parse Netlink message to retrieve the bridge MAC address. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_nl_mac_addr *data = arg; + struct ndmsg *r = NLMSG_DATA(nh); + struct rtattr *attribute; + int len; + + len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); + for (attribute = MLX5_NDA_RTA(r); + RTA_OK(attribute, len); + attribute = RTA_NEXT(attribute, len)) { + if (attribute->rta_type == NDA_LLADDR) { + if (data->mac_n == MLX5_MAX_MAC_ADDRESSES) { + DRV_LOG(WARNING, + "not enough room to finalize the" + " request"); + rte_errno = ENOMEM; + return -rte_errno; + } +#ifdef RTE_LIBRTE_MLX5_DEBUG + char m[18]; + + rte_ether_format_addr(m, 18, RTA_DATA(attribute)); + DRV_LOG(DEBUG, "bridge MAC address %s", m); +#endif + memcpy(&(*data->mac)[data->mac_n++], + RTA_DATA(attribute), RTE_ETHER_ADDR_LEN); + } + } + return 0; +} + +/** + * Get bridge MAC addresses. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac[out] + * Pointer to the array table of MAC addresses to fill. + * Its size should be of MLX5_MAX_MAC_ADDRESSES. + * @param mac_n[out] + * Number of entries filled in MAC array. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_list(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr (*mac)[], int *mac_n) +{ + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_GETNEIGH, + .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, + }, + .ifm = { + .ifi_family = PF_BRIDGE, + .ifi_index = iface_idx, + }, + }; + struct mlx5_nl_mac_addr data = { + .mac = mac, + .mac_n = 0, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + if (nlsk_fd == -1) + return 0; + ret = mlx5_nl_request(nlsk_fd, &req.hdr, sn, &req.ifm, + sizeof(struct ifinfomsg)); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_mac_addr_cb, &data); + if (ret < 0) + goto error; + *mac_n = data.mac_n; + return 0; +error: + DRV_LOG(DEBUG, "Interface %u cannot retrieve MAC address list %s", + iface_idx, strerror(rte_errno)); + return -rte_errno; +} + +/** + * Modify the MAC address neighbour table with Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac + * MAC address to consider. + * @param add + * 1 to add the MAC address, 0 to remove the MAC address. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int add) +{ + struct { + struct nlmsghdr hdr; + struct ndmsg ndm; + struct rtattr rta; + uint8_t buffer[RTE_ETHER_ADDR_LEN]; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | + NLM_F_EXCL | NLM_F_ACK, + .nlmsg_type = add ? RTM_NEWNEIGH : RTM_DELNEIGH, + }, + .ndm = { + .ndm_family = PF_BRIDGE, + .ndm_state = NUD_NOARP | NUD_PERMANENT, + .ndm_ifindex = iface_idx, + .ndm_flags = NTF_SELF, + }, + .rta = { + .rta_type = NDA_LLADDR, + .rta_len = RTA_LENGTH(RTE_ETHER_ADDR_LEN), + }, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + if (nlsk_fd == -1) + return 0; + memcpy(RTA_DATA(&req.rta), mac, RTE_ETHER_ADDR_LEN); + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_ALIGN(req.rta.rta_len); + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) + goto error; + return 0; +error: + DRV_LOG(DEBUG, + "Interface %u cannot %s MAC address" + " %02X:%02X:%02X:%02X:%02X:%02X %s", + iface_idx, + add ? "add" : "remove", + mac->addr_bytes[0], mac->addr_bytes[1], + mac->addr_bytes[2], mac->addr_bytes[3], + mac->addr_bytes[4], mac->addr_bytes[5], + strerror(rte_errno)); + return -rte_errno; +} + +/** + * Modify the VF MAC address neighbour table with Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac + * MAC address to consider. + * @param vf_index + * VF index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int vf_index) +{ + int ret; + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + struct rtattr vf_list_rta; + struct rtattr vf_info_rta; + struct rtattr vf_mac_rta; + struct ifla_vf_mac ivm; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + .nlmsg_type = RTM_BASE, + }, + .ifm = { + .ifi_index = iface_idx, + }, + .vf_list_rta = { + .rta_type = IFLA_VFINFO_LIST, + .rta_len = RTA_ALIGN(RTA_LENGTH(0)), + }, + .vf_info_rta = { + .rta_type = IFLA_VF_INFO, + .rta_len = RTA_ALIGN(RTA_LENGTH(0)), + }, + .vf_mac_rta = { + .rta_type = IFLA_VF_MAC, + }, + }; + struct ifla_vf_mac ivm = { + .vf = vf_index, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + + memcpy(&ivm.mac, mac, RTE_ETHER_ADDR_LEN); + memcpy(RTA_DATA(&req.vf_mac_rta), &ivm, sizeof(ivm)); + + req.vf_mac_rta.rta_len = RTA_LENGTH(sizeof(ivm)); + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_ALIGN(req.vf_list_rta.rta_len) + + RTA_ALIGN(req.vf_info_rta.rta_len) + + RTA_ALIGN(req.vf_mac_rta.rta_len); + req.vf_list_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), + &req.vf_list_rta); + req.vf_info_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), + &req.vf_info_rta); + + if (nlsk_fd < 0) + return -1; + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) + goto error; + return 0; +error: + DRV_LOG(ERR, + "representor %u cannot set VF MAC address " + "%02X:%02X:%02X:%02X:%02X:%02X : %s", + vf_index, + mac->addr_bytes[0], mac->addr_bytes[1], + mac->addr_bytes[2], mac->addr_bytes[3], + mac->addr_bytes[4], mac->addr_bytes[5], + strerror(rte_errno)); + return -rte_errno; +} + +/** + * Add a MAC address. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + * @param mac + * MAC address to register. + * @param index + * MAC address index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, + uint32_t index) +{ + int ret; + + ret = mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 1); + if (!ret) { + MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); + if (index >= MLX5_MAX_MAC_ADDRESSES) + return -EINVAL; + + BITFIELD_SET(mac_own, index); + } + if (ret == -EEXIST) + return 0; + return ret; +} + +/** + * Remove a MAC address. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + * @param mac + * MAC address to remove. + * @param index + * MAC address index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index) +{ + MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); + if (index >= MLX5_MAX_MAC_ADDRESSES) + return -EINVAL; + + BITFIELD_RESET(mac_own, index); + return mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 0); +} + +/** + * Synchronize Netlink bridge table to the internal table. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_addrs + * Mac addresses array to sync. + * @param n + * @p mac_addrs array size. + */ +void +mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n) +{ + struct rte_ether_addr macs[n]; + int macs_n = 0; + int i; + int ret; + + ret = mlx5_nl_mac_addr_list(nlsk_fd, iface_idx, &macs, &macs_n); + if (ret) + return; + for (i = 0; i != macs_n; ++i) { + int j; + + /* Verify the address is not in the array yet. */ + for (j = 0; j != n; ++j) + if (rte_is_same_ether_addr(&macs[i], &mac_addrs[j])) + break; + if (j != n) + continue; + /* Find the first entry available. */ + for (j = 0; j != n; ++j) { + if (rte_is_zero_ether_addr(&mac_addrs[j])) { + mac_addrs[j] = macs[i]; + break; + } + } + } +} + +/** + * Flush all added MAC addresses. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param[in] mac_addrs + * Mac addresses array to flush. + * @param n + * @p mac_addrs array size. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + */ +void +mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own) +{ + int i; + + if (n <= 0 || n >= MLX5_MAX_MAC_ADDRESSES) + return; + + for (i = n - 1; i >= 0; --i) { + struct rte_ether_addr *m = &mac_addrs[i]; + + if (BITFIELD_ISSET(mac_own, i)) + mlx5_nl_mac_addr_remove(nlsk_fd, iface_idx, mac_own, m, + i); + } +} + +/** + * Enable promiscuous / all multicast mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param flags + * IFF_PROMISC for promiscuous, IFF_ALLMULTI for allmulti. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_device_flags(int nlsk_fd, unsigned int iface_idx, uint32_t flags, + int enable) +{ + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifi; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_NEWLINK, + .nlmsg_flags = NLM_F_REQUEST, + }, + .ifi = { + .ifi_flags = enable ? flags : 0, + .ifi_change = flags, + .ifi_index = iface_idx, + }, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + MLX5_ASSERT(!(flags & ~(IFF_PROMISC | IFF_ALLMULTI))); + if (nlsk_fd < 0) + return 0; + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + return ret; + return 0; +} + +/** + * Enable promiscuous mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable) +{ + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_PROMISC, enable); + + if (ret) + DRV_LOG(DEBUG, + "Interface %u cannot %s promisc mode: Netlink error %s", + iface_idx, enable ? "enable" : "disable", + strerror(rte_errno)); + return ret; +} + +/** + * Enable all multicast mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable) +{ + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_ALLMULTI, + enable); + + if (ret) + DRV_LOG(DEBUG, + "Interface %u cannot %s allmulti : Netlink error %s", + iface_idx, enable ? "enable" : "disable", + strerror(rte_errno)); + return ret; +} + +/** + * Process network interface information from Netlink message. + * + * @param nh + * Pointer to Netlink message header. + * @param arg + * Opaque data pointer for this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_cmdget_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_nl_ifindex_data *data = arg; + struct mlx5_nl_ifindex_data local = { + .flags = 0, + }; + size_t off = NLMSG_HDRLEN; + + if (nh->nlmsg_type != + RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET) && + nh->nlmsg_type != + RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_PORT_GET)) + goto error; + while (off < nh->nlmsg_len) { + struct nlattr *na = (void *)((uintptr_t)nh + off); + void *payload = (void *)((uintptr_t)na + NLA_HDRLEN); + + if (na->nla_len > nh->nlmsg_len - off) + goto error; + switch (na->nla_type) { + case RDMA_NLDEV_ATTR_DEV_INDEX: + local.ibindex = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_IB_INDEX; + break; + case RDMA_NLDEV_ATTR_DEV_NAME: + if (!strcmp(payload, data->name)) + local.flags |= MLX5_NL_CMD_GET_IB_NAME; + break; + case RDMA_NLDEV_ATTR_NDEV_INDEX: + local.ifindex = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_NET_INDEX; + break; + case RDMA_NLDEV_ATTR_PORT_INDEX: + local.portnum = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_PORT_INDEX; + break; + default: + break; + } + off += NLA_ALIGN(na->nla_len); + } + /* + * It is possible to have multiple messages for all + * Infiniband devices in the system with appropriate name. + * So we should gather parameters locally and copy to + * query context only in case of coinciding device name. + */ + if (local.flags & MLX5_NL_CMD_GET_IB_NAME) { + data->flags = local.flags; + data->ibindex = local.ibindex; + data->ifindex = local.ifindex; + data->portnum = local.portnum; + } + return 0; +error: + rte_errno = EINVAL; + return -rte_errno; +} + +/** + * Get index of network interface associated with some IB device. + * + * This is the only somewhat safe method to avoid resorting to heuristics + * when faced with port representors. Unfortunately it requires at least + * Linux 4.17. + * + * @param nl + * Netlink socket of the RDMA kind (NETLINK_RDMA). + * @param[in] name + * IB device name. + * @param[in] pindex + * IB device port index, starting from 1 + * @return + * A valid (nonzero) interface index on success, 0 otherwise and rte_errno + * is set. + */ +unsigned int +mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex) +{ + struct mlx5_nl_ifindex_data data = { + .name = name, + .flags = 0, + .ibindex = 0, /* Determined during first pass. */ + .ifindex = 0, /* Determined during second pass. */ + }; + union { + struct nlmsghdr nh; + uint8_t buf[NLMSG_HDRLEN + + NLA_HDRLEN + NLA_ALIGN(sizeof(data.ibindex)) + + NLA_HDRLEN + NLA_ALIGN(sizeof(pindex))]; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH(0), + .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_GET), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, + }, + }; + struct nlattr *na; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX)) + goto error; + data.flags = 0; + sn = MLX5_NL_SN_GENERATE; + req.nh.nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_PORT_GET); + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.buf) - NLMSG_HDRLEN); + na = (void *)((uintptr_t)req.buf + NLMSG_HDRLEN); + na->nla_len = NLA_HDRLEN + sizeof(data.ibindex); + na->nla_type = RDMA_NLDEV_ATTR_DEV_INDEX; + memcpy((void *)((uintptr_t)na + NLA_HDRLEN), + &data.ibindex, sizeof(data.ibindex)); + na = (void *)((uintptr_t)na + NLA_ALIGN(na->nla_len)); + na->nla_len = NLA_HDRLEN + sizeof(pindex); + na->nla_type = RDMA_NLDEV_ATTR_PORT_INDEX; + memcpy((void *)((uintptr_t)na + NLA_HDRLEN), + &pindex, sizeof(pindex)); + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || + !(data.flags & MLX5_NL_CMD_GET_NET_INDEX) || + !data.ifindex) + goto error; + return data.ifindex; +error: + rte_errno = ENODEV; + return 0; +} + +/** + * Get the number of physical ports of given IB device. + * + * @param nl + * Netlink socket of the RDMA kind (NETLINK_RDMA). + * @param[in] name + * IB device name. + * + * @return + * A valid (nonzero) number of ports on success, 0 otherwise + * and rte_errno is set. + */ +unsigned int +mlx5_nl_portnum(int nl, const char *name) +{ + struct mlx5_nl_ifindex_data data = { + .flags = 0, + .name = name, + .ifindex = 0, + .portnum = 0, + }; + struct nlmsghdr req = { + .nlmsg_len = NLMSG_LENGTH(0), + .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_GET), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || + !(data.flags & MLX5_NL_CMD_GET_PORT_INDEX)) { + rte_errno = ENODEV; + return 0; + } + if (!data.portnum) + rte_errno = EINVAL; + return data.portnum; +} + +/** + * Analyze gathered port parameters via Netlink to recognize master + * and representor devices for E-Switch configuration. + * + * @param[in] num_vf_set + * flag of presence of number of VFs port attribute. + * @param[inout] switch_info + * Port information, including port name as a number and port name + * type if recognized + * + * @return + * master and representor flags are set in switch_info according to + * recognized parameters (if any). + */ +static void +mlx5_nl_check_switch_info(bool num_vf_set, + struct mlx5_switch_info *switch_info) +{ + switch (switch_info->name_type) { + case MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN: + /* + * Name is not recognized, assume the master, + * check the number of VFs key presence. + */ + switch_info->master = num_vf_set; + break; + case MLX5_PHYS_PORT_NAME_TYPE_NOTSET: + /* + * Name is not set, this assumes the legacy naming + * schema for master, just check if there is a + * number of VFs key. + */ + switch_info->master = num_vf_set; + break; + case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: + /* New uplink naming schema recognized. */ + switch_info->master = 1; + break; + case MLX5_PHYS_PORT_NAME_TYPE_LEGACY: + /* Legacy representors naming schema. */ + switch_info->representor = !num_vf_set; + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFVF: + /* New representors naming schema. */ + switch_info->representor = 1; + break; + } +} + +/** + * Process switch information from Netlink message. + * + * @param nh + * Pointer to Netlink message header. + * @param arg + * Opaque data pointer for this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_switch_info info = { + .master = 0, + .representor = 0, + .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET, + .port_name = 0, + .switch_id = 0, + }; + size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + bool switch_id_set = false; + bool num_vf_set = false; + + if (nh->nlmsg_type != RTM_NEWLINK) + goto error; + while (off < nh->nlmsg_len) { + struct rtattr *ra = (void *)((uintptr_t)nh + off); + void *payload = RTA_DATA(ra); + unsigned int i; + + if (ra->rta_len > nh->nlmsg_len - off) + goto error; + switch (ra->rta_type) { + case IFLA_NUM_VF: + num_vf_set = true; + break; + case IFLA_PHYS_PORT_NAME: + mlx5_translate_port_name((char *)payload, &info); + break; + case IFLA_PHYS_SWITCH_ID: + info.switch_id = 0; + for (i = 0; i < RTA_PAYLOAD(ra); ++i) { + info.switch_id <<= 8; + info.switch_id |= ((uint8_t *)payload)[i]; + } + switch_id_set = true; + break; + } + off += RTA_ALIGN(ra->rta_len); + } + if (switch_id_set) { + /* We have some E-Switch configuration. */ + mlx5_nl_check_switch_info(num_vf_set, &info); + } + MLX5_ASSERT(!(info.master && info.representor)); + memcpy(arg, &info, sizeof(info)); + return 0; +error: + rte_errno = EINVAL; + return -rte_errno; +} + +/** + * Get switch information associated with network interface. + * + * @param nl + * Netlink socket of the ROUTE kind (NETLINK_ROUTE). + * @param ifindex + * Network interface index. + * @param[out] info + * Switch information object, populated in case of success. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info) +{ + struct { + struct nlmsghdr nh; + struct ifinfomsg info; + struct rtattr rta; + uint32_t extmask; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH + (sizeof(req.info) + + RTA_LENGTH(sizeof(uint32_t))), + .nlmsg_type = RTM_GETLINK, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + }, + .info = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex, + }, + .rta = { + .rta_type = IFLA_EXT_MASK, + .rta_len = RTA_LENGTH(sizeof(int32_t)), + }, + .extmask = RTE_LE32(1), + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nl, sn, mlx5_nl_switch_info_cb, info); + if (info->master && info->representor) { + DRV_LOG(ERR, "ifindex %u device is recognized as master" + " and as representor", ifindex); + rte_errno = ENODEV; + ret = -rte_errno; + } + return ret; +} + +/* + * Delete VLAN network device by ifindex. + * + * @param[in] tcf + * Context object initialized by mlx5_nl_vlan_vmwa_init(). + * @param[in] ifindex + * Interface index of network device to delete. + */ +void +mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex) +{ + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + struct { + struct nlmsghdr nh; + struct ifinfomsg info; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_DELLINK, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + }, + .info = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex, + }, + }; + + if (ifindex) { + ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); + if (ret < 0) + DRV_LOG(WARNING, "netlink: error deleting VLAN WA" + " ifindex %u, %d", ifindex, ret); + } +} + +/* Set of subroutines to build Netlink message. */ +static struct nlattr * +nl_msg_tail(struct nlmsghdr *nlh) +{ + return (struct nlattr *) + (((uint8_t *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len)); +} + +static void +nl_attr_put(struct nlmsghdr *nlh, int type, const void *data, int alen) +{ + struct nlattr *nla = nl_msg_tail(nlh); + + nla->nla_type = type; + nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr)) + alen; + nlh->nlmsg_len += NLMSG_ALIGN(nla->nla_len); + + if (alen) + memcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen); +} + +static struct nlattr * +nl_attr_nest_start(struct nlmsghdr *nlh, int type) +{ + struct nlattr *nest = (struct nlattr *)nl_msg_tail(nlh); + + nl_attr_put(nlh, type, NULL, 0); + return nest; +} + +static void +nl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *nest) +{ + nest->nla_len = (uint8_t *)nl_msg_tail(nlh) - (uint8_t *)nest; +} + +/* + * Create network VLAN device with specified VLAN tag. + * + * @param[in] tcf + * Context object initialized by mlx5_nl_vlan_vmwa_init(). + * @param[in] ifindex + * Base network interface index. + * @param[in] tag + * VLAN tag for VLAN network device to create. + */ +uint32_t +mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex, uint16_t tag) +{ + struct nlmsghdr *nlh; + struct ifinfomsg *ifm; + char name[sizeof(MLX5_VMWA_VLAN_DEVICE_PFX) + 32]; + + __rte_cache_aligned + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifinfomsg)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 8 + + NLMSG_ALIGN(sizeof(uint32_t)) + + NLMSG_ALIGN(sizeof(name)) + + NLMSG_ALIGN(sizeof("vlan")) + + NLMSG_ALIGN(sizeof(uint32_t)) + + NLMSG_ALIGN(sizeof(uint16_t)) + 16]; + struct nlattr *na_info; + struct nlattr *na_vlan; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = RTM_NEWLINK; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | + NLM_F_EXCL | NLM_F_ACK; + ifm = (struct ifinfomsg *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct ifinfomsg); + ifm->ifi_family = AF_UNSPEC; + ifm->ifi_type = 0; + ifm->ifi_index = 0; + ifm->ifi_flags = IFF_UP; + ifm->ifi_change = 0xffffffff; + nl_attr_put(nlh, IFLA_LINK, &ifindex, sizeof(ifindex)); + ret = snprintf(name, sizeof(name), "%s.%u.%u", + MLX5_VMWA_VLAN_DEVICE_PFX, ifindex, tag); + nl_attr_put(nlh, IFLA_IFNAME, name, ret + 1); + na_info = nl_attr_nest_start(nlh, IFLA_LINKINFO); + nl_attr_put(nlh, IFLA_INFO_KIND, "vlan", sizeof("vlan")); + na_vlan = nl_attr_nest_start(nlh, IFLA_INFO_DATA); + nl_attr_put(nlh, IFLA_VLAN_ID, &tag, sizeof(tag)); + nl_attr_nest_end(nlh, na_vlan); + nl_attr_nest_end(nlh, na_info); + MLX5_ASSERT(sizeof(buf) >= nlh->nlmsg_len); + ret = mlx5_nl_send(vmwa->nl_socket, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(WARNING, "netlink: VLAN %s create failure (%d)", name, + ret); + } + // Try to get ifindex of created or pre-existing device. + ret = if_nametoindex(name); + if (!ret) { + DRV_LOG(WARNING, "VLAN %s failed to get index (%d)", name, + errno); + return 0; + } + return ret; +} + +/** + * Parse Netlink message to retrieve the general family ID. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_family_id_cb(struct nlmsghdr *nh, void *arg) +{ + + struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); + struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr))); + + for (; nla->nla_len && nla < tail; + nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len))) { + if (nla->nla_type == CTRL_ATTR_FAMILY_ID) { + *(uint16_t *)arg = *(uint16_t *)(nla + 1); + return 0; + } + } + return -EINVAL; +} + +#define MLX5_NL_MAX_ATTR_SIZE 100 +/** + * Get generic netlink family ID. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] name + * The family name. + * + * @return + * ID >= 0 on success and @p enable is updated, a negative errno value + * otherwise and rte_errno is set. + */ +static int +mlx5_nl_generic_family_id_get(int nlsk_fd, const char *name) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int name_size = strlen(name) + 1; + int ret; + uint16_t id = -1; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE)]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = GENL_ID_CTRL; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = CTRL_CMD_GETFAMILY; + genl->version = 1; + nl_attr_put(nlh, CTRL_ATTR_FAMILY_NAME, name, name_size); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_family_id_cb, &id); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to get Netlink %s family ID: %d.", name, + ret); + return ret; + } + DRV_LOG(DEBUG, "Netlink \"%s\" family ID is %u.", name, id); + return (int)id; +} + +/** + * Get Devlink family ID. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * + * @return + * ID >= 0 on success and @p enable is updated, a negative errno value + * otherwise and rte_errno is set. + */ + +int +mlx5_nl_devlink_family_id_get(int nlsk_fd) +{ + return mlx5_nl_generic_family_id_get(nlsk_fd, DEVLINK_GENL_NAME); +} + +/** + * Parse Netlink message to retrieve the ROCE enable status. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_roce_cb(struct nlmsghdr *nh, void *arg) +{ + + int ret = -EINVAL; + int *enable = arg; + struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); + struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr))); + + while (nla->nla_len && nla < tail) { + switch (nla->nla_type) { + /* Expected nested attributes case. */ + case DEVLINK_ATTR_PARAM: + case DEVLINK_ATTR_PARAM_VALUES_LIST: + case DEVLINK_ATTR_PARAM_VALUE: + ret = 0; + nla += 1; + break; + case DEVLINK_ATTR_PARAM_VALUE_DATA: + *enable = 1; + return 0; + default: + nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len)); + } + } + *enable = 0; + return ret; +} + +/** + * Get ROCE enable status through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * Where to store the enable status. + * + * @return + * 0 on success and @p enable is updated, a negative errno value otherwise + * and rte_errno is set. + */ +int +mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, + int *enable) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + int cur_en = 0; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 4 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 4]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_PARAM_GET; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_roce_cb, &cur_en); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to get ROCE enable on device %s: %d.", + pci_addr, ret); + return ret; + } + *enable = cur_en; + DRV_LOG(DEBUG, "ROCE is %sabled for device \"%s\".", + cur_en ? "en" : "dis", pci_addr); + return ret; +} + +/** + * Reload mlx5 device kernel driver through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * The enable status to set. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 2 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 2]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_RELOAD; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to reload %s device by Netlink - %d", + pci_addr, ret); + return ret; + } + DRV_LOG(DEBUG, "Device \"%s\" was reloaded by Netlink successfully.", + pci_addr); + return 0; +} + +/** + * Set ROCE enable status through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * The enable status to set. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, + int enable) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 6 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 6]; + uint8_t cmode = DEVLINK_PARAM_CMODE_DRIVERINIT; + uint8_t ptype = NLA_FLAG; +; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_PARAM_SET; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, &cmode, sizeof(cmode)); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_TYPE, &ptype, sizeof(ptype)); + if (enable) + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, NULL, 0); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to %sable ROCE for device %s by Netlink:" + " %d.", enable ? "en" : "dis", pci_addr, ret); + return ret; + } + DRV_LOG(DEBUG, "Device %s ROCE was %sabled by Netlink successfully.", + pci_addr, enable ? "en" : "dis"); + /* Now, need to reload the driver. */ + return mlx5_nl_driver_reload(nlsk_fd, family_id, pci_addr); +} diff --git a/drivers/common/mlx5/linux/mlx5_nl.h b/drivers/common/mlx5/linux/mlx5_nl.h new file mode 100644 index 0000000..53021e1 --- /dev/null +++ b/drivers/common/mlx5/linux/mlx5_nl.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_NL_H_ +#define RTE_PMD_MLX5_NL_H_ + +#include + +#include + +#include "mlx5_common.h" + + +/* VLAN netdev for VLAN workaround. */ +struct mlx5_nl_vlan_dev { + uint32_t refcnt; + uint32_t ifindex; /**< Own interface index. */ +}; + +/* + * Array of VLAN devices created on the base of VF + * used for workaround in virtual environments. + */ +struct mlx5_nl_vlan_vmwa_context { + int nl_socket; + uint32_t vf_ifindex; + struct mlx5_nl_vlan_dev vlan_dev[4096]; +}; + +__rte_internal +int mlx5_nl_init(int protocol); +__rte_internal +int mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index); +__rte_internal +int mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, + uint32_t index); +__rte_internal +void mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n); +__rte_internal +void mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own); +__rte_internal +int mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable); +__rte_internal +int mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable); +__rte_internal +unsigned int mlx5_nl_portnum(int nl, const char *name); +__rte_internal +unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); +__rte_internal +int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int vf_index); +__rte_internal +int mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info); + +__rte_internal +void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex); +__rte_internal +uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex, uint16_t tag); +__rte_internal +int mlx5_nl_devlink_family_id_get(int nlsk_fd); +__rte_internal +int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, + int *enable); +__rte_internal +int mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr); +__rte_internal +int mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, + int enable); + +#endif /* RTE_PMD_MLX5_NL_H_ */ diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 9806865..0a8980f 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -13,7 +13,6 @@ deps += ['hash', 'pci', 'net', 'eal', 'kvargs'] sources += files( 'mlx5_devx_cmds.c', 'mlx5_common.c', - 'mlx5_nl.c', 'mlx5_common_mp.c', 'mlx5_common_mr.c', ) diff --git a/drivers/common/mlx5/mlx5_nl.c b/drivers/common/mlx5/mlx5_nl.c deleted file mode 100644 index 1a1033a..0000000 --- a/drivers/common/mlx5/mlx5_nl.c +++ /dev/null @@ -1,1721 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mlx5_nl.h" -#include "mlx5_common_utils.h" -#ifdef HAVE_DEVLINK -#include -#endif - - -/* Size of the buffer to receive kernel messages */ -#define MLX5_NL_BUF_SIZE (32 * 1024) -/* Send buffer size for the Netlink socket */ -#define MLX5_SEND_BUF_SIZE 32768 -/* Receive buffer size for the Netlink socket */ -#define MLX5_RECV_BUF_SIZE 32768 - -/** Parameters of VLAN devices created by driver. */ -#define MLX5_VMWA_VLAN_DEVICE_PFX "evmlx" -/* - * Define NDA_RTA as defined in iproute2 sources. - * - * see in iproute2 sources file include/libnetlink.h - */ -#ifndef MLX5_NDA_RTA -#define MLX5_NDA_RTA(r) \ - ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) -#endif -/* - * Define NLMSG_TAIL as defined in iproute2 sources. - * - * see in iproute2 sources file include/libnetlink.h - */ -#ifndef NLMSG_TAIL -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *)(((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) -#endif -/* - * The following definitions are normally found in rdma/rdma_netlink.h, - * however they are so recent that most systems do not expose them yet. - */ -#ifndef HAVE_RDMA_NL_NLDEV -#define RDMA_NL_NLDEV 5 -#endif -#ifndef HAVE_RDMA_NLDEV_CMD_GET -#define RDMA_NLDEV_CMD_GET 1 -#endif -#ifndef HAVE_RDMA_NLDEV_CMD_PORT_GET -#define RDMA_NLDEV_CMD_PORT_GET 5 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_INDEX -#define RDMA_NLDEV_ATTR_DEV_INDEX 1 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_NAME -#define RDMA_NLDEV_ATTR_DEV_NAME 2 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_PORT_INDEX -#define RDMA_NLDEV_ATTR_PORT_INDEX 3 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX -#define RDMA_NLDEV_ATTR_NDEV_INDEX 50 -#endif - -/* These are normally found in linux/if_link.h. */ -#ifndef HAVE_IFLA_NUM_VF -#define IFLA_NUM_VF 21 -#endif -#ifndef HAVE_IFLA_EXT_MASK -#define IFLA_EXT_MASK 29 -#endif -#ifndef HAVE_IFLA_PHYS_SWITCH_ID -#define IFLA_PHYS_SWITCH_ID 36 -#endif -#ifndef HAVE_IFLA_PHYS_PORT_NAME -#define IFLA_PHYS_PORT_NAME 38 -#endif - -/* - * Some Devlink defines may be missed in old kernel versions, - * adjust used defines. - */ -#ifndef DEVLINK_GENL_NAME -#define DEVLINK_GENL_NAME "devlink" -#endif -#ifndef DEVLINK_GENL_VERSION -#define DEVLINK_GENL_VERSION 1 -#endif -#ifndef DEVLINK_ATTR_BUS_NAME -#define DEVLINK_ATTR_BUS_NAME 1 -#endif -#ifndef DEVLINK_ATTR_DEV_NAME -#define DEVLINK_ATTR_DEV_NAME 2 -#endif -#ifndef DEVLINK_ATTR_PARAM -#define DEVLINK_ATTR_PARAM 80 -#endif -#ifndef DEVLINK_ATTR_PARAM_NAME -#define DEVLINK_ATTR_PARAM_NAME 81 -#endif -#ifndef DEVLINK_ATTR_PARAM_TYPE -#define DEVLINK_ATTR_PARAM_TYPE 83 -#endif -#ifndef DEVLINK_ATTR_PARAM_VALUES_LIST -#define DEVLINK_ATTR_PARAM_VALUES_LIST 84 -#endif -#ifndef DEVLINK_ATTR_PARAM_VALUE -#define DEVLINK_ATTR_PARAM_VALUE 85 -#endif -#ifndef DEVLINK_ATTR_PARAM_VALUE_DATA -#define DEVLINK_ATTR_PARAM_VALUE_DATA 86 -#endif -#ifndef DEVLINK_ATTR_PARAM_VALUE_CMODE -#define DEVLINK_ATTR_PARAM_VALUE_CMODE 87 -#endif -#ifndef DEVLINK_PARAM_CMODE_DRIVERINIT -#define DEVLINK_PARAM_CMODE_DRIVERINIT 1 -#endif -#ifndef DEVLINK_CMD_RELOAD -#define DEVLINK_CMD_RELOAD 37 -#endif -#ifndef DEVLINK_CMD_PARAM_GET -#define DEVLINK_CMD_PARAM_GET 38 -#endif -#ifndef DEVLINK_CMD_PARAM_SET -#define DEVLINK_CMD_PARAM_SET 39 -#endif -#ifndef NLA_FLAG -#define NLA_FLAG 6 -#endif - -/* Add/remove MAC address through Netlink */ -struct mlx5_nl_mac_addr { - struct rte_ether_addr (*mac)[]; - /**< MAC address handled by the device. */ - int mac_n; /**< Number of addresses in the array. */ -}; - -#define MLX5_NL_CMD_GET_IB_NAME (1 << 0) -#define MLX5_NL_CMD_GET_IB_INDEX (1 << 1) -#define MLX5_NL_CMD_GET_NET_INDEX (1 << 2) -#define MLX5_NL_CMD_GET_PORT_INDEX (1 << 3) - -/** Data structure used by mlx5_nl_cmdget_cb(). */ -struct mlx5_nl_ifindex_data { - const char *name; /**< IB device name (in). */ - uint32_t flags; /**< found attribute flags (out). */ - uint32_t ibindex; /**< IB device index (out). */ - uint32_t ifindex; /**< Network interface index (out). */ - uint32_t portnum; /**< IB device max port number (out). */ -}; - -rte_atomic32_t atomic_sn = RTE_ATOMIC32_INIT(0); - -/* Generate Netlink sequence number. */ -#define MLX5_NL_SN_GENERATE ((uint32_t)rte_atomic32_add_return(&atomic_sn, 1)) - -/** - * Opens a Netlink socket. - * - * @param protocol - * Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA). - * - * @return - * A file descriptor on success, a negative errno value otherwise and - * rte_errno is set. - */ -int -mlx5_nl_init(int protocol) -{ - int fd; - int sndbuf_size = MLX5_SEND_BUF_SIZE; - int rcvbuf_size = MLX5_RECV_BUF_SIZE; - struct sockaddr_nl local = { - .nl_family = AF_NETLINK, - }; - int ret; - - fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); - if (fd == -1) { - rte_errno = errno; - return -rte_errno; - } - ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(int)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, sizeof(int)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - ret = bind(fd, (struct sockaddr *)&local, sizeof(local)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - return fd; -error: - close(fd); - return -rte_errno; -} - -/** - * Send a request message to the kernel on the Netlink socket. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] nh - * The Netlink message send to the kernel. - * @param[in] ssn - * Sequence number. - * @param[in] req - * Pointer to the request structure. - * @param[in] len - * Length of the request in bytes. - * - * @return - * The number of sent bytes on success, a negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_nl_request(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn, void *req, - int len) -{ - struct sockaddr_nl sa = { - .nl_family = AF_NETLINK, - }; - struct iovec iov[2] = { - { .iov_base = nh, .iov_len = sizeof(*nh), }, - { .iov_base = req, .iov_len = len, }, - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = iov, - .msg_iovlen = 2, - }; - int send_bytes; - - nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ - nh->nlmsg_seq = sn; - send_bytes = sendmsg(nlsk_fd, &msg, 0); - if (send_bytes < 0) { - rte_errno = errno; - return -rte_errno; - } - return send_bytes; -} - -/** - * Send a message to the kernel on the Netlink socket. - * - * @param[in] nlsk_fd - * The Netlink socket file descriptor used for communication. - * @param[in] nh - * The Netlink message send to the kernel. - * @param[in] sn - * Sequence number. - * - * @return - * The number of sent bytes on success, a negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_nl_send(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn) -{ - struct sockaddr_nl sa = { - .nl_family = AF_NETLINK, - }; - struct iovec iov = { - .iov_base = nh, - .iov_len = nh->nlmsg_len, - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - int send_bytes; - - nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ - nh->nlmsg_seq = sn; - send_bytes = sendmsg(nlsk_fd, &msg, 0); - if (send_bytes < 0) { - rte_errno = errno; - return -rte_errno; - } - return send_bytes; -} - -/** - * Receive a message from the kernel on the Netlink socket, following - * mlx5_nl_send(). - * - * @param[in] nlsk_fd - * The Netlink socket file descriptor used for communication. - * @param[in] sn - * Sequence number. - * @param[in] cb - * The callback function to call for each Netlink message received. - * @param[in, out] arg - * Custom arguments for the callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), - void *arg) -{ - struct sockaddr_nl sa; - void *buf = malloc(MLX5_RECV_BUF_SIZE); - struct iovec iov = { - .iov_base = buf, - .iov_len = MLX5_RECV_BUF_SIZE, - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = &iov, - /* One message at a time */ - .msg_iovlen = 1, - }; - int multipart = 0; - int ret = 0; - - if (!buf) { - rte_errno = ENOMEM; - return -rte_errno; - } - do { - struct nlmsghdr *nh; - int recv_bytes = 0; - - do { - recv_bytes = recvmsg(nlsk_fd, &msg, 0); - if (recv_bytes == -1) { - rte_errno = errno; - ret = -rte_errno; - goto exit; - } - nh = (struct nlmsghdr *)buf; - } while (nh->nlmsg_seq != sn); - for (; - NLMSG_OK(nh, (unsigned int)recv_bytes); - nh = NLMSG_NEXT(nh, recv_bytes)) { - if (nh->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err_data = NLMSG_DATA(nh); - - if (err_data->error < 0) { - rte_errno = -err_data->error; - ret = -rte_errno; - goto exit; - } - /* Ack message. */ - ret = 0; - goto exit; - } - /* Multi-part msgs and their trailing DONE message. */ - if (nh->nlmsg_flags & NLM_F_MULTI) { - if (nh->nlmsg_type == NLMSG_DONE) { - ret = 0; - goto exit; - } - multipart = 1; - } - if (cb) { - ret = cb(nh, arg); - if (ret < 0) - goto exit; - } - } - } while (multipart); -exit: - free(buf); - return ret; -} - -/** - * Parse Netlink message to retrieve the bridge MAC address. - * - * @param nh - * Pointer to Netlink Message Header. - * @param arg - * PMD data register with this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_nl_mac_addr *data = arg; - struct ndmsg *r = NLMSG_DATA(nh); - struct rtattr *attribute; - int len; - - len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); - for (attribute = MLX5_NDA_RTA(r); - RTA_OK(attribute, len); - attribute = RTA_NEXT(attribute, len)) { - if (attribute->rta_type == NDA_LLADDR) { - if (data->mac_n == MLX5_MAX_MAC_ADDRESSES) { - DRV_LOG(WARNING, - "not enough room to finalize the" - " request"); - rte_errno = ENOMEM; - return -rte_errno; - } -#ifdef RTE_LIBRTE_MLX5_DEBUG - char m[18]; - - rte_ether_format_addr(m, 18, RTA_DATA(attribute)); - DRV_LOG(DEBUG, "bridge MAC address %s", m); -#endif - memcpy(&(*data->mac)[data->mac_n++], - RTA_DATA(attribute), RTE_ETHER_ADDR_LEN); - } - } - return 0; -} - -/** - * Get bridge MAC addresses. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac[out] - * Pointer to the array table of MAC addresses to fill. - * Its size should be of MLX5_MAX_MAC_ADDRESSES. - * @param mac_n[out] - * Number of entries filled in MAC array. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_list(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr (*mac)[], int *mac_n) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifm; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_GETNEIGH, - .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, - }, - .ifm = { - .ifi_family = PF_BRIDGE, - .ifi_index = iface_idx, - }, - }; - struct mlx5_nl_mac_addr data = { - .mac = mac, - .mac_n = 0, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - if (nlsk_fd == -1) - return 0; - ret = mlx5_nl_request(nlsk_fd, &req.hdr, sn, &req.ifm, - sizeof(struct ifinfomsg)); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_mac_addr_cb, &data); - if (ret < 0) - goto error; - *mac_n = data.mac_n; - return 0; -error: - DRV_LOG(DEBUG, "Interface %u cannot retrieve MAC address list %s", - iface_idx, strerror(rte_errno)); - return -rte_errno; -} - -/** - * Modify the MAC address neighbour table with Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac - * MAC address to consider. - * @param add - * 1 to add the MAC address, 0 to remove the MAC address. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int add) -{ - struct { - struct nlmsghdr hdr; - struct ndmsg ndm; - struct rtattr rta; - uint8_t buffer[RTE_ETHER_ADDR_LEN]; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_EXCL | NLM_F_ACK, - .nlmsg_type = add ? RTM_NEWNEIGH : RTM_DELNEIGH, - }, - .ndm = { - .ndm_family = PF_BRIDGE, - .ndm_state = NUD_NOARP | NUD_PERMANENT, - .ndm_ifindex = iface_idx, - .ndm_flags = NTF_SELF, - }, - .rta = { - .rta_type = NDA_LLADDR, - .rta_len = RTA_LENGTH(RTE_ETHER_ADDR_LEN), - }, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - if (nlsk_fd == -1) - return 0; - memcpy(RTA_DATA(&req.rta), mac, RTE_ETHER_ADDR_LEN); - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_ALIGN(req.rta.rta_len); - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) - goto error; - return 0; -error: - DRV_LOG(DEBUG, - "Interface %u cannot %s MAC address" - " %02X:%02X:%02X:%02X:%02X:%02X %s", - iface_idx, - add ? "add" : "remove", - mac->addr_bytes[0], mac->addr_bytes[1], - mac->addr_bytes[2], mac->addr_bytes[3], - mac->addr_bytes[4], mac->addr_bytes[5], - strerror(rte_errno)); - return -rte_errno; -} - -/** - * Modify the VF MAC address neighbour table with Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac - * MAC address to consider. - * @param vf_index - * VF index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int vf_index) -{ - int ret; - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifm; - struct rtattr vf_list_rta; - struct rtattr vf_info_rta; - struct rtattr vf_mac_rta; - struct ifla_vf_mac ivm; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - .nlmsg_type = RTM_BASE, - }, - .ifm = { - .ifi_index = iface_idx, - }, - .vf_list_rta = { - .rta_type = IFLA_VFINFO_LIST, - .rta_len = RTA_ALIGN(RTA_LENGTH(0)), - }, - .vf_info_rta = { - .rta_type = IFLA_VF_INFO, - .rta_len = RTA_ALIGN(RTA_LENGTH(0)), - }, - .vf_mac_rta = { - .rta_type = IFLA_VF_MAC, - }, - }; - struct ifla_vf_mac ivm = { - .vf = vf_index, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - - memcpy(&ivm.mac, mac, RTE_ETHER_ADDR_LEN); - memcpy(RTA_DATA(&req.vf_mac_rta), &ivm, sizeof(ivm)); - - req.vf_mac_rta.rta_len = RTA_LENGTH(sizeof(ivm)); - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_ALIGN(req.vf_list_rta.rta_len) + - RTA_ALIGN(req.vf_info_rta.rta_len) + - RTA_ALIGN(req.vf_mac_rta.rta_len); - req.vf_list_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), - &req.vf_list_rta); - req.vf_info_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), - &req.vf_info_rta); - - if (nlsk_fd < 0) - return -1; - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) - goto error; - return 0; -error: - DRV_LOG(ERR, - "representor %u cannot set VF MAC address " - "%02X:%02X:%02X:%02X:%02X:%02X : %s", - vf_index, - mac->addr_bytes[0], mac->addr_bytes[1], - mac->addr_bytes[2], mac->addr_bytes[3], - mac->addr_bytes[4], mac->addr_bytes[5], - strerror(rte_errno)); - return -rte_errno; -} - -/** - * Add a MAC address. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - * @param mac - * MAC address to register. - * @param index - * MAC address index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, - uint64_t *mac_own, struct rte_ether_addr *mac, - uint32_t index) -{ - int ret; - - ret = mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 1); - if (!ret) { - MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); - if (index >= MLX5_MAX_MAC_ADDRESSES) - return -EINVAL; - - BITFIELD_SET(mac_own, index); - } - if (ret == -EEXIST) - return 0; - return ret; -} - -/** - * Remove a MAC address. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - * @param mac - * MAC address to remove. - * @param index - * MAC address index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, - struct rte_ether_addr *mac, uint32_t index) -{ - MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); - if (index >= MLX5_MAX_MAC_ADDRESSES) - return -EINVAL; - - BITFIELD_RESET(mac_own, index); - return mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 0); -} - -/** - * Synchronize Netlink bridge table to the internal table. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_addrs - * Mac addresses array to sync. - * @param n - * @p mac_addrs array size. - */ -void -mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n) -{ - struct rte_ether_addr macs[n]; - int macs_n = 0; - int i; - int ret; - - ret = mlx5_nl_mac_addr_list(nlsk_fd, iface_idx, &macs, &macs_n); - if (ret) - return; - for (i = 0; i != macs_n; ++i) { - int j; - - /* Verify the address is not in the array yet. */ - for (j = 0; j != n; ++j) - if (rte_is_same_ether_addr(&macs[i], &mac_addrs[j])) - break; - if (j != n) - continue; - /* Find the first entry available. */ - for (j = 0; j != n; ++j) { - if (rte_is_zero_ether_addr(&mac_addrs[j])) { - mac_addrs[j] = macs[i]; - break; - } - } - } -} - -/** - * Flush all added MAC addresses. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param[in] mac_addrs - * Mac addresses array to flush. - * @param n - * @p mac_addrs array size. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - */ -void -mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n, - uint64_t *mac_own) -{ - int i; - - if (n <= 0 || n >= MLX5_MAX_MAC_ADDRESSES) - return; - - for (i = n - 1; i >= 0; --i) { - struct rte_ether_addr *m = &mac_addrs[i]; - - if (BITFIELD_ISSET(mac_own, i)) - mlx5_nl_mac_addr_remove(nlsk_fd, iface_idx, mac_own, m, - i); - } -} - -/** - * Enable promiscuous / all multicast mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param flags - * IFF_PROMISC for promiscuous, IFF_ALLMULTI for allmulti. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_device_flags(int nlsk_fd, unsigned int iface_idx, uint32_t flags, - int enable) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifi; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_NEWLINK, - .nlmsg_flags = NLM_F_REQUEST, - }, - .ifi = { - .ifi_flags = enable ? flags : 0, - .ifi_change = flags, - .ifi_index = iface_idx, - }, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - MLX5_ASSERT(!(flags & ~(IFF_PROMISC | IFF_ALLMULTI))); - if (nlsk_fd < 0) - return 0; - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - return ret; - return 0; -} - -/** - * Enable promiscuous mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable) -{ - int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_PROMISC, enable); - - if (ret) - DRV_LOG(DEBUG, - "Interface %u cannot %s promisc mode: Netlink error %s", - iface_idx, enable ? "enable" : "disable", - strerror(rte_errno)); - return ret; -} - -/** - * Enable all multicast mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable) -{ - int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_ALLMULTI, - enable); - - if (ret) - DRV_LOG(DEBUG, - "Interface %u cannot %s allmulti : Netlink error %s", - iface_idx, enable ? "enable" : "disable", - strerror(rte_errno)); - return ret; -} - -/** - * Process network interface information from Netlink message. - * - * @param nh - * Pointer to Netlink message header. - * @param arg - * Opaque data pointer for this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_cmdget_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_nl_ifindex_data *data = arg; - struct mlx5_nl_ifindex_data local = { - .flags = 0, - }; - size_t off = NLMSG_HDRLEN; - - if (nh->nlmsg_type != - RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET) && - nh->nlmsg_type != - RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_PORT_GET)) - goto error; - while (off < nh->nlmsg_len) { - struct nlattr *na = (void *)((uintptr_t)nh + off); - void *payload = (void *)((uintptr_t)na + NLA_HDRLEN); - - if (na->nla_len > nh->nlmsg_len - off) - goto error; - switch (na->nla_type) { - case RDMA_NLDEV_ATTR_DEV_INDEX: - local.ibindex = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_IB_INDEX; - break; - case RDMA_NLDEV_ATTR_DEV_NAME: - if (!strcmp(payload, data->name)) - local.flags |= MLX5_NL_CMD_GET_IB_NAME; - break; - case RDMA_NLDEV_ATTR_NDEV_INDEX: - local.ifindex = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_NET_INDEX; - break; - case RDMA_NLDEV_ATTR_PORT_INDEX: - local.portnum = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_PORT_INDEX; - break; - default: - break; - } - off += NLA_ALIGN(na->nla_len); - } - /* - * It is possible to have multiple messages for all - * Infiniband devices in the system with appropriate name. - * So we should gather parameters locally and copy to - * query context only in case of coinciding device name. - */ - if (local.flags & MLX5_NL_CMD_GET_IB_NAME) { - data->flags = local.flags; - data->ibindex = local.ibindex; - data->ifindex = local.ifindex; - data->portnum = local.portnum; - } - return 0; -error: - rte_errno = EINVAL; - return -rte_errno; -} - -/** - * Get index of network interface associated with some IB device. - * - * This is the only somewhat safe method to avoid resorting to heuristics - * when faced with port representors. Unfortunately it requires at least - * Linux 4.17. - * - * @param nl - * Netlink socket of the RDMA kind (NETLINK_RDMA). - * @param[in] name - * IB device name. - * @param[in] pindex - * IB device port index, starting from 1 - * @return - * A valid (nonzero) interface index on success, 0 otherwise and rte_errno - * is set. - */ -unsigned int -mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex) -{ - struct mlx5_nl_ifindex_data data = { - .name = name, - .flags = 0, - .ibindex = 0, /* Determined during first pass. */ - .ifindex = 0, /* Determined during second pass. */ - }; - union { - struct nlmsghdr nh; - uint8_t buf[NLMSG_HDRLEN + - NLA_HDRLEN + NLA_ALIGN(sizeof(data.ibindex)) + - NLA_HDRLEN + NLA_ALIGN(sizeof(pindex))]; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH(0), - .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_GET), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, - }, - }; - struct nlattr *na; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX)) - goto error; - data.flags = 0; - sn = MLX5_NL_SN_GENERATE; - req.nh.nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_PORT_GET); - req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.buf) - NLMSG_HDRLEN); - na = (void *)((uintptr_t)req.buf + NLMSG_HDRLEN); - na->nla_len = NLA_HDRLEN + sizeof(data.ibindex); - na->nla_type = RDMA_NLDEV_ATTR_DEV_INDEX; - memcpy((void *)((uintptr_t)na + NLA_HDRLEN), - &data.ibindex, sizeof(data.ibindex)); - na = (void *)((uintptr_t)na + NLA_ALIGN(na->nla_len)); - na->nla_len = NLA_HDRLEN + sizeof(pindex); - na->nla_type = RDMA_NLDEV_ATTR_PORT_INDEX; - memcpy((void *)((uintptr_t)na + NLA_HDRLEN), - &pindex, sizeof(pindex)); - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || - !(data.flags & MLX5_NL_CMD_GET_NET_INDEX) || - !data.ifindex) - goto error; - return data.ifindex; -error: - rte_errno = ENODEV; - return 0; -} - -/** - * Get the number of physical ports of given IB device. - * - * @param nl - * Netlink socket of the RDMA kind (NETLINK_RDMA). - * @param[in] name - * IB device name. - * - * @return - * A valid (nonzero) number of ports on success, 0 otherwise - * and rte_errno is set. - */ -unsigned int -mlx5_nl_portnum(int nl, const char *name) -{ - struct mlx5_nl_ifindex_data data = { - .flags = 0, - .name = name, - .ifindex = 0, - .portnum = 0, - }; - struct nlmsghdr req = { - .nlmsg_len = NLMSG_LENGTH(0), - .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_GET), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || - !(data.flags & MLX5_NL_CMD_GET_PORT_INDEX)) { - rte_errno = ENODEV; - return 0; - } - if (!data.portnum) - rte_errno = EINVAL; - return data.portnum; -} - -/** - * Analyze gathered port parameters via Netlink to recognize master - * and representor devices for E-Switch configuration. - * - * @param[in] num_vf_set - * flag of presence of number of VFs port attribute. - * @param[inout] switch_info - * Port information, including port name as a number and port name - * type if recognized - * - * @return - * master and representor flags are set in switch_info according to - * recognized parameters (if any). - */ -static void -mlx5_nl_check_switch_info(bool num_vf_set, - struct mlx5_switch_info *switch_info) -{ - switch (switch_info->name_type) { - case MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN: - /* - * Name is not recognized, assume the master, - * check the number of VFs key presence. - */ - switch_info->master = num_vf_set; - break; - case MLX5_PHYS_PORT_NAME_TYPE_NOTSET: - /* - * Name is not set, this assumes the legacy naming - * schema for master, just check if there is a - * number of VFs key. - */ - switch_info->master = num_vf_set; - break; - case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: - /* New uplink naming schema recognized. */ - switch_info->master = 1; - break; - case MLX5_PHYS_PORT_NAME_TYPE_LEGACY: - /* Legacy representors naming schema. */ - switch_info->representor = !num_vf_set; - break; - case MLX5_PHYS_PORT_NAME_TYPE_PFVF: - /* New representors naming schema. */ - switch_info->representor = 1; - break; - } -} - -/** - * Process switch information from Netlink message. - * - * @param nh - * Pointer to Netlink message header. - * @param arg - * Opaque data pointer for this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_switch_info info = { - .master = 0, - .representor = 0, - .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET, - .port_name = 0, - .switch_id = 0, - }; - size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - bool switch_id_set = false; - bool num_vf_set = false; - - if (nh->nlmsg_type != RTM_NEWLINK) - goto error; - while (off < nh->nlmsg_len) { - struct rtattr *ra = (void *)((uintptr_t)nh + off); - void *payload = RTA_DATA(ra); - unsigned int i; - - if (ra->rta_len > nh->nlmsg_len - off) - goto error; - switch (ra->rta_type) { - case IFLA_NUM_VF: - num_vf_set = true; - break; - case IFLA_PHYS_PORT_NAME: - mlx5_translate_port_name((char *)payload, &info); - break; - case IFLA_PHYS_SWITCH_ID: - info.switch_id = 0; - for (i = 0; i < RTA_PAYLOAD(ra); ++i) { - info.switch_id <<= 8; - info.switch_id |= ((uint8_t *)payload)[i]; - } - switch_id_set = true; - break; - } - off += RTA_ALIGN(ra->rta_len); - } - if (switch_id_set) { - /* We have some E-Switch configuration. */ - mlx5_nl_check_switch_info(num_vf_set, &info); - } - MLX5_ASSERT(!(info.master && info.representor)); - memcpy(arg, &info, sizeof(info)); - return 0; -error: - rte_errno = EINVAL; - return -rte_errno; -} - -/** - * Get switch information associated with network interface. - * - * @param nl - * Netlink socket of the ROUTE kind (NETLINK_ROUTE). - * @param ifindex - * Network interface index. - * @param[out] info - * Switch information object, populated in case of success. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_switch_info(int nl, unsigned int ifindex, - struct mlx5_switch_info *info) -{ - struct { - struct nlmsghdr nh; - struct ifinfomsg info; - struct rtattr rta; - uint32_t extmask; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH - (sizeof(req.info) + - RTA_LENGTH(sizeof(uint32_t))), - .nlmsg_type = RTM_GETLINK, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - }, - .info = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex, - }, - .rta = { - .rta_type = IFLA_EXT_MASK, - .rta_len = RTA_LENGTH(sizeof(int32_t)), - }, - .extmask = RTE_LE32(1), - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nl, sn, mlx5_nl_switch_info_cb, info); - if (info->master && info->representor) { - DRV_LOG(ERR, "ifindex %u device is recognized as master" - " and as representor", ifindex); - rte_errno = ENODEV; - ret = -rte_errno; - } - return ret; -} - -/* - * Delete VLAN network device by ifindex. - * - * @param[in] tcf - * Context object initialized by mlx5_nl_vlan_vmwa_init(). - * @param[in] ifindex - * Interface index of network device to delete. - */ -void -mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex) -{ - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - struct { - struct nlmsghdr nh; - struct ifinfomsg info; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_DELLINK, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - }, - .info = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex, - }, - }; - - if (ifindex) { - ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); - if (ret < 0) - DRV_LOG(WARNING, "netlink: error deleting VLAN WA" - " ifindex %u, %d", ifindex, ret); - } -} - -/* Set of subroutines to build Netlink message. */ -static struct nlattr * -nl_msg_tail(struct nlmsghdr *nlh) -{ - return (struct nlattr *) - (((uint8_t *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len)); -} - -static void -nl_attr_put(struct nlmsghdr *nlh, int type, const void *data, int alen) -{ - struct nlattr *nla = nl_msg_tail(nlh); - - nla->nla_type = type; - nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr)) + alen; - nlh->nlmsg_len += NLMSG_ALIGN(nla->nla_len); - - if (alen) - memcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen); -} - -static struct nlattr * -nl_attr_nest_start(struct nlmsghdr *nlh, int type) -{ - struct nlattr *nest = (struct nlattr *)nl_msg_tail(nlh); - - nl_attr_put(nlh, type, NULL, 0); - return nest; -} - -static void -nl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *nest) -{ - nest->nla_len = (uint8_t *)nl_msg_tail(nlh) - (uint8_t *)nest; -} - -/* - * Create network VLAN device with specified VLAN tag. - * - * @param[in] tcf - * Context object initialized by mlx5_nl_vlan_vmwa_init(). - * @param[in] ifindex - * Base network interface index. - * @param[in] tag - * VLAN tag for VLAN network device to create. - */ -uint32_t -mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex, uint16_t tag) -{ - struct nlmsghdr *nlh; - struct ifinfomsg *ifm; - char name[sizeof(MLX5_VMWA_VLAN_DEVICE_PFX) + 32]; - - __rte_cache_aligned - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct ifinfomsg)) + - NLMSG_ALIGN(sizeof(struct nlattr)) * 8 + - NLMSG_ALIGN(sizeof(uint32_t)) + - NLMSG_ALIGN(sizeof(name)) + - NLMSG_ALIGN(sizeof("vlan")) + - NLMSG_ALIGN(sizeof(uint32_t)) + - NLMSG_ALIGN(sizeof(uint16_t)) + 16]; - struct nlattr *na_info; - struct nlattr *na_vlan; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = RTM_NEWLINK; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_EXCL | NLM_F_ACK; - ifm = (struct ifinfomsg *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct ifinfomsg); - ifm->ifi_family = AF_UNSPEC; - ifm->ifi_type = 0; - ifm->ifi_index = 0; - ifm->ifi_flags = IFF_UP; - ifm->ifi_change = 0xffffffff; - nl_attr_put(nlh, IFLA_LINK, &ifindex, sizeof(ifindex)); - ret = snprintf(name, sizeof(name), "%s.%u.%u", - MLX5_VMWA_VLAN_DEVICE_PFX, ifindex, tag); - nl_attr_put(nlh, IFLA_IFNAME, name, ret + 1); - na_info = nl_attr_nest_start(nlh, IFLA_LINKINFO); - nl_attr_put(nlh, IFLA_INFO_KIND, "vlan", sizeof("vlan")); - na_vlan = nl_attr_nest_start(nlh, IFLA_INFO_DATA); - nl_attr_put(nlh, IFLA_VLAN_ID, &tag, sizeof(tag)); - nl_attr_nest_end(nlh, na_vlan); - nl_attr_nest_end(nlh, na_info); - MLX5_ASSERT(sizeof(buf) >= nlh->nlmsg_len); - ret = mlx5_nl_send(vmwa->nl_socket, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); - if (ret < 0) { - DRV_LOG(WARNING, "netlink: VLAN %s create failure (%d)", name, - ret); - } - // Try to get ifindex of created or pre-existing device. - ret = if_nametoindex(name); - if (!ret) { - DRV_LOG(WARNING, "VLAN %s failed to get index (%d)", name, - errno); - return 0; - } - return ret; -} - -/** - * Parse Netlink message to retrieve the general family ID. - * - * @param nh - * Pointer to Netlink Message Header. - * @param arg - * PMD data register with this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_family_id_cb(struct nlmsghdr *nh, void *arg) -{ - - struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); - struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr))); - - for (; nla->nla_len && nla < tail; - nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len))) { - if (nla->nla_type == CTRL_ATTR_FAMILY_ID) { - *(uint16_t *)arg = *(uint16_t *)(nla + 1); - return 0; - } - } - return -EINVAL; -} - -#define MLX5_NL_MAX_ATTR_SIZE 100 -/** - * Get generic netlink family ID. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] name - * The family name. - * - * @return - * ID >= 0 on success and @p enable is updated, a negative errno value - * otherwise and rte_errno is set. - */ -static int -mlx5_nl_generic_family_id_get(int nlsk_fd, const char *name) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *genl; - uint32_t sn = MLX5_NL_SN_GENERATE; - int name_size = strlen(name) + 1; - int ret; - uint16_t id = -1; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr)) + - NLMSG_ALIGN(sizeof(struct nlattr)) + - NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE)]; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = GENL_ID_CTRL; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - genl = (struct genlmsghdr *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct genlmsghdr); - genl->cmd = CTRL_CMD_GETFAMILY; - genl->version = 1; - nl_attr_put(nlh, CTRL_ATTR_FAMILY_NAME, name, name_size); - ret = mlx5_nl_send(nlsk_fd, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_family_id_cb, &id); - if (ret < 0) { - DRV_LOG(DEBUG, "Failed to get Netlink %s family ID: %d.", name, - ret); - return ret; - } - DRV_LOG(DEBUG, "Netlink \"%s\" family ID is %u.", name, id); - return (int)id; -} - -/** - * Get Devlink family ID. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * - * @return - * ID >= 0 on success and @p enable is updated, a negative errno value - * otherwise and rte_errno is set. - */ - -int -mlx5_nl_devlink_family_id_get(int nlsk_fd) -{ - return mlx5_nl_generic_family_id_get(nlsk_fd, DEVLINK_GENL_NAME); -} - -/** - * Parse Netlink message to retrieve the ROCE enable status. - * - * @param nh - * Pointer to Netlink Message Header. - * @param arg - * PMD data register with this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_roce_cb(struct nlmsghdr *nh, void *arg) -{ - - int ret = -EINVAL; - int *enable = arg; - struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); - struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr))); - - while (nla->nla_len && nla < tail) { - switch (nla->nla_type) { - /* Expected nested attributes case. */ - case DEVLINK_ATTR_PARAM: - case DEVLINK_ATTR_PARAM_VALUES_LIST: - case DEVLINK_ATTR_PARAM_VALUE: - ret = 0; - nla += 1; - break; - case DEVLINK_ATTR_PARAM_VALUE_DATA: - *enable = 1; - return 0; - default: - nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len)); - } - } - *enable = 0; - return ret; -} - -/** - * Get ROCE enable status through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] family_id - * the Devlink family ID. - * @param pci_addr - * The device PCI address. - * @param[out] enable - * Where to store the enable status. - * - * @return - * 0 on success and @p enable is updated, a negative errno value otherwise - * and rte_errno is set. - */ -int -mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, - int *enable) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *genl; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - int cur_en = 0; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr)) + - NLMSG_ALIGN(sizeof(struct nlattr)) * 4 + - NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 4]; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = family_id; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - genl = (struct genlmsghdr *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct genlmsghdr); - genl->cmd = DEVLINK_CMD_PARAM_GET; - genl->version = DEVLINK_GENL_VERSION; - nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); - nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); - nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); - ret = mlx5_nl_send(nlsk_fd, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_roce_cb, &cur_en); - if (ret < 0) { - DRV_LOG(DEBUG, "Failed to get ROCE enable on device %s: %d.", - pci_addr, ret); - return ret; - } - *enable = cur_en; - DRV_LOG(DEBUG, "ROCE is %sabled for device \"%s\".", - cur_en ? "en" : "dis", pci_addr); - return ret; -} - -/** - * Reload mlx5 device kernel driver through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] family_id - * the Devlink family ID. - * @param pci_addr - * The device PCI address. - * @param[out] enable - * The enable status to set. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *genl; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr)) + - NLMSG_ALIGN(sizeof(struct nlattr)) * 2 + - NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 2]; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = family_id; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - genl = (struct genlmsghdr *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct genlmsghdr); - genl->cmd = DEVLINK_CMD_RELOAD; - genl->version = DEVLINK_GENL_VERSION; - nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); - nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); - ret = mlx5_nl_send(nlsk_fd, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) { - DRV_LOG(DEBUG, "Failed to reload %s device by Netlink - %d", - pci_addr, ret); - return ret; - } - DRV_LOG(DEBUG, "Device \"%s\" was reloaded by Netlink successfully.", - pci_addr); - return 0; -} - -/** - * Set ROCE enable status through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] family_id - * the Devlink family ID. - * @param pci_addr - * The device PCI address. - * @param[out] enable - * The enable status to set. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, - int enable) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *genl; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct genlmsghdr)) + - NLMSG_ALIGN(sizeof(struct nlattr)) * 6 + - NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 6]; - uint8_t cmode = DEVLINK_PARAM_CMODE_DRIVERINIT; - uint8_t ptype = NLA_FLAG; -; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = family_id; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - genl = (struct genlmsghdr *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct genlmsghdr); - genl->cmd = DEVLINK_CMD_PARAM_SET; - genl->version = DEVLINK_GENL_VERSION; - nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); - nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); - nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); - nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, &cmode, sizeof(cmode)); - nl_attr_put(nlh, DEVLINK_ATTR_PARAM_TYPE, &ptype, sizeof(ptype)); - if (enable) - nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, NULL, 0); - ret = mlx5_nl_send(nlsk_fd, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) { - DRV_LOG(DEBUG, "Failed to %sable ROCE for device %s by Netlink:" - " %d.", enable ? "en" : "dis", pci_addr, ret); - return ret; - } - DRV_LOG(DEBUG, "Device %s ROCE was %sabled by Netlink successfully.", - pci_addr, enable ? "en" : "dis"); - /* Now, need to reload the driver. */ - return mlx5_nl_driver_reload(nlsk_fd, family_id, pci_addr); -} diff --git a/drivers/common/mlx5/mlx5_nl.h b/drivers/common/mlx5/mlx5_nl.h deleted file mode 100644 index 53021e1..0000000 --- a/drivers/common/mlx5/mlx5_nl.h +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2019 Mellanox Technologies, Ltd - */ - -#ifndef RTE_PMD_MLX5_NL_H_ -#define RTE_PMD_MLX5_NL_H_ - -#include - -#include - -#include "mlx5_common.h" - - -/* VLAN netdev for VLAN workaround. */ -struct mlx5_nl_vlan_dev { - uint32_t refcnt; - uint32_t ifindex; /**< Own interface index. */ -}; - -/* - * Array of VLAN devices created on the base of VF - * used for workaround in virtual environments. - */ -struct mlx5_nl_vlan_vmwa_context { - int nl_socket; - uint32_t vf_ifindex; - struct mlx5_nl_vlan_dev vlan_dev[4096]; -}; - -__rte_internal -int mlx5_nl_init(int protocol); -__rte_internal -int mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, - struct rte_ether_addr *mac, uint32_t index); -__rte_internal -int mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, - uint64_t *mac_own, struct rte_ether_addr *mac, - uint32_t index); -__rte_internal -void mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n); -__rte_internal -void mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n, - uint64_t *mac_own); -__rte_internal -int mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable); -__rte_internal -int mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable); -__rte_internal -unsigned int mlx5_nl_portnum(int nl, const char *name); -__rte_internal -unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); -__rte_internal -int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int vf_index); -__rte_internal -int mlx5_nl_switch_info(int nl, unsigned int ifindex, - struct mlx5_switch_info *info); - -__rte_internal -void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex); -__rte_internal -uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex, uint16_t tag); -__rte_internal -int mlx5_nl_devlink_family_id_get(int nlsk_fd); -__rte_internal -int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, - int *enable); -__rte_internal -int mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr); -__rte_internal -int mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, - int enable); - -#endif /* RTE_PMD_MLX5_NL_H_ */ From patchwork Wed May 27 16:14:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ophir Munk X-Patchwork-Id: 70658 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C2BA4A0093; Wed, 27 May 2020 18:14:45 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2A8091D545; Wed, 27 May 2020 18:14:45 +0200 (CEST) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70075.outbound.protection.outlook.com [40.107.7.75]) by dpdk.org (Postfix) with ESMTP id 12C601D420 for ; Wed, 27 May 2020 18:14:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=E9wikCQ9QjgqsuV3LokguHrMJJgNGkK0LiqFxCXTZt8Y4KTbQLVi0hg6Sg6cbh1rCyyyzI4Hs4USWBhpeLGaVu4q4IABYn4Zx7NAA2DlC56wZDH+RgCRfPHpyBtgFecXhFRH55+EPaVHldSIbdoQc5yE08c7Z70GZolC1mM/yOnBydVFTdRD+ImlTzdIr0T3zE8daMkLtXpPU49khN4PXV7kH6N48mDuPXQzwPDVhMb4Neg1XPuxXcqaM86IKmYt9/iJuyhgrQW567Cfu6aZ+xmASckfNAdlrBHoQdUGZ3IouKTyxZwqxYXCwprEzBWHjxU95pOkooN2YG1UtUDTpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DxeSoul1I/MHmMhmeDLMIIqTS8R3ccHCo+xaM1lmkys=; b=Fm9eCaScd+kBuTiUqaFb+85+RLp7WLGzPNfxBit1lkiVzXqH4nHZcowjzEK53JDHDVVRKZXOJobF9X8I71XWs1OTS2Jksnfbff4GTdtlM1ZITNCJsNT4ADWljkSkHX2hEAm2XtavIjTiim0Uf2tXRm1VyYoFlM2BBJAb+6fXZirhlkeONm+78vA+jP8Yjh1U5YKwibcPblA9ZlZVBz9poO4EW/8GXRnhp8qddUZvjlGTAQu2OBDryHpXY9O8Lf4c/rULJrNt93eddwhp5c1jIh3sUT6U/249Ag21Alz2cQ4TUsOHpxroxRB2bK6Nlk4GoIMzBbQpplz40KoPJGFiaQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DxeSoul1I/MHmMhmeDLMIIqTS8R3ccHCo+xaM1lmkys=; b=dVxaOEcpNp/z1HPYn7aYAwHUZPG5KeBrbCc+gy032Jw/7aL4/ojKLPblRWpvwdhpiAltHc9NLXXCHI+m6tGMM20ExY65YGtGdzpN1ZeqwXhPwOqZh8zLCEJKJVGSxlgk8qK0r7CFDOq4FYBJMEGuacO0oW9VYsva+tNhAkNi6xc= Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=mellanox.com; Received: from AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) by AM0PR05MB4497.eurprd05.prod.outlook.com (2603:10a6:208:67::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.24; Wed, 27 May 2020 16:14:41 +0000 Received: from AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a]) by AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a%3]) with mapi id 15.20.3021.029; Wed, 27 May 2020 16:14:41 +0000 From: Ophir Munk To: dev@dpdk.org, Matan Azrad Cc: Ophir Munk Date: Wed, 27 May 2020 16:14:25 +0000 Message-Id: <20200527161425.22944-3-ophirmu@mellanox.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20200527161425.22944-1-ophirmu@mellanox.com> References: <20200527161425.22944-1-ophirmu@mellanox.com> X-ClientProxiedBy: AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) To AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from mellanox.com (37.142.13.130) by AM0PR10CA0108.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:e6::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.18 via Frontend Transport; Wed, 27 May 2020 16:14:41 +0000 X-Mailer: git-send-email 2.8.4 X-Originating-IP: [37.142.13.130] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c10c2e60-d02a-4f4e-a178-08d802590fe2 X-MS-TrafficTypeDiagnostic: AM0PR05MB4497: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:265; X-Forefront-PRVS: 04163EF38A X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: a2Zf2lLR8ZciWrYrzLwRLvImC/S870WGMLBTwcBQw2MrCIU6WxNs2XM05zZxW9e2FXv29/0Ejts9ziSSiavZG5JOiq63w0sa9/73D1u3GNY21Dko8obqnrbrF+vPmyZJnplKJsFAFAIKwFZNfIiRxtmmO9Ur209ub5jOCZAzNMi6ztvmhKDs0rpGVwO6RhrNrfP/q70MfGxlo706P3PB+DYWhxjWZUG2I6DzVle+NDJVWcmF9N5XoccX6fZcbdoRkXR94TrSn9/s2cTlnoez/Hij4W8LznauHxOED7duip9T8bgAp04XuM4Bne8qFLibjxVa29jOu1axE4FA0Bg4Dg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM0PR05MB4209.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(39860400002)(376002)(346002)(396003)(366004)(136003)(2906002)(6636002)(7696005)(8886007)(1076003)(26005)(8676002)(5660300002)(37006003)(52116002)(36756003)(186003)(16526019)(30864003)(6666004)(83380400001)(8936002)(316002)(478600001)(66946007)(66556008)(86362001)(2616005)(956004)(66476007)(6862004)(107886003)(4326008)(55016002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: RdZwuVZuTczPCn712OSBehWBB+07m1QIgcC2C/iG8nHKrM4fN+ip0gt5hP9Na3C8D1siPDQ4Z/6RXF87kTh/vkXQ1sOGO6y9rAyv8GND9ejsyomtAOf2uKR/44P/rpKcL2oOFuM9Is5LX3JMQS6qeRdIO0Hz8gRCCc3iGHs2CRZt+vxTAW8OxXuFF7bIIXBTJz2cgBWlLpmGHUNpeUpCpUhInnFeXLHCq514JSny3VMzrDUZYFB2LDT6er3IWVYtdyigVHqb4iFQFWw8dongkj1lw/8ezfZTiIX5JqVwzMswtDbFY+5no74UyRPdKeysOyO+uIBQqsLOP8durTqZtz2Kbrm4OEfy/5QOnM1eRAF5Ti2XKamwge4+Fb2PMl+gHXnpI632bSJM9EerBOWRW50lqEct8xxNUy+uTnRvHhSS91sZCuOoG6MZXL9dPiD1QFczH0doD2GSEEaa3KbWeQoB6GFUV3AKvQzvjNNx/wk= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: c10c2e60-d02a-4f4e-a178-08d802590fe2 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 May 2020 16:14:41.6779 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: T+x242v+hSIbKYJBuzv0Qjmb28Rh+QpiTh+8qXJFkbbPx9jaMHpcuKyez1j5P4nkbqTTQJ652Jdlgf6RN7KNYg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4497 Subject: [dpdk-dev] [PATCH v1 3/3] common/mlx5: split common file under Linux directory X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" File mlx5_common.c includes both specific and non-specific Linux APIs. Move the Linux specific APIS into a new file named linux/mlx5_common_os.c. Signed-off-by: Ophir Munk --- drivers/common/mlx5/Makefile | 1 + drivers/common/mlx5/linux/meson.build | 1 + drivers/common/mlx5/linux/mlx5_common_os.c | 305 +++++++++++++++++++++++++++++ drivers/common/mlx5/mlx5_common.c | 286 +-------------------------- drivers/common/mlx5/mlx5_common.h | 1 + 5 files changed, 310 insertions(+), 284 deletions(-) create mode 100644 drivers/common/mlx5/linux/mlx5_common_os.c diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 40bf2a5..e9863b5 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -16,6 +16,7 @@ SRCS-y += linux/mlx5_glue.c endif SRCS-y += mlx5_devx_cmds.c SRCS-y += mlx5_common.c +SRCS-y += linux/mlx5_common_os.c SRCS-y += linux/mlx5_nl.c SRCS-y += mlx5_common_mp.c SRCS-y += mlx5_common_mr.c diff --git a/drivers/common/mlx5/linux/meson.build b/drivers/common/mlx5/linux/meson.build index 04f7e03..f0016fa 100644 --- a/drivers/common/mlx5/linux/meson.build +++ b/drivers/common/mlx5/linux/meson.build @@ -46,6 +46,7 @@ if static_ibverbs endif sources += files('mlx5_nl.c') +sources += files('mlx5_common_os.c') if not dlopen_ibverbs sources += files('mlx5_glue.c') endif diff --git a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c new file mode 100644 index 0000000..4e04d70 --- /dev/null +++ b/drivers/common/mlx5/linux/mlx5_common_os.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#ifdef RTE_IBVERBS_LINK_DLOPEN +#include +#endif + +#include + +#include "mlx5_common.h" +#include "mlx5_common_utils.h" +#include "mlx5_glue.h" + +#ifdef MLX5_GLUE +const struct mlx5_glue *mlx5_glue; +#endif + +/** + * Get PCI information by sysfs device path. + * + * @param dev_path + * Pointer to device sysfs folder name. + * @param[out] pci_addr + * PCI bus address output buffer. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_dev_to_pci_addr(const char *dev_path, + struct rte_pci_addr *pci_addr) +{ + FILE *file; + char line[32]; + MKSTR(path, "%s/device/uevent", dev_path); + + file = fopen(path, "rb"); + if (file == NULL) { + rte_errno = errno; + return -rte_errno; + } + while (fgets(line, sizeof(line), file) == line) { + size_t len = strlen(line); + int ret; + + /* Truncate long lines. */ + if (len == (sizeof(line) - 1)) + while (line[(len - 1)] != '\n') { + ret = fgetc(file); + if (ret == EOF) + break; + line[(len - 1)] = ret; + } + /* Extract information. */ + if (sscanf(line, + "PCI_SLOT_NAME=" + "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n", + &pci_addr->domain, + &pci_addr->bus, + &pci_addr->devid, + &pci_addr->function) == 4) { + ret = 0; + break; + } + } + fclose(file); + return 0; +} + +/** + * Extract port name, as a number, from sysfs or netlink information. + * + * @param[in] port_name_in + * String representing the port name. + * @param[out] port_info_out + * Port information, including port name as a number and port name + * type if recognized + * + * @return + * port_name field set according to recognized name format. + */ +void +mlx5_translate_port_name(const char *port_name_in, + struct mlx5_switch_info *port_info_out) +{ + char pf_c1, pf_c2, vf_c1, vf_c2; + char *end; + int sc_items; + + /* + * Check for port-name as a string of the form pf0vf0 + * (support kernel ver >= 5.0 or OFED ver >= 4.6). + */ + sc_items = sscanf(port_name_in, "%c%c%d%c%c%d", + &pf_c1, &pf_c2, &port_info_out->pf_num, + &vf_c1, &vf_c2, &port_info_out->port_name); + if (sc_items == 6 && + pf_c1 == 'p' && pf_c2 == 'f' && + vf_c1 == 'v' && vf_c2 == 'f') { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_PFVF; + return; + } + /* + * Check for port-name as a string of the form p0 + * (support kernel ver >= 5.0, or OFED ver >= 4.6). + */ + sc_items = sscanf(port_name_in, "%c%d", + &pf_c1, &port_info_out->port_name); + if (sc_items == 2 && pf_c1 == 'p') { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK; + return; + } + /* Check for port-name as a number (support kernel ver < 5.0 */ + errno = 0; + port_info_out->port_name = strtol(port_name_in, &end, 0); + if (!errno && + (size_t)(end - port_name_in) == strlen(port_name_in)) { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_LEGACY; + return; + } + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; +} + +#ifdef MLX5_GLUE + +/** + * Suffix RTE_EAL_PMD_PATH with "-glue". + * + * This function performs a sanity check on RTE_EAL_PMD_PATH before + * suffixing its last component. + * + * @param buf[out] + * Output buffer, should be large enough otherwise NULL is returned. + * @param size + * Size of @p out. + * + * @return + * Pointer to @p buf or @p NULL in case suffix cannot be appended. + */ +static char * +mlx5_glue_path(char *buf, size_t size) +{ + static const char *const bad[] = { "/", ".", "..", NULL }; + const char *path = RTE_EAL_PMD_PATH; + size_t len = strlen(path); + size_t off; + int i; + + while (len && path[len - 1] == '/') + --len; + for (off = len; off && path[off - 1] != '/'; --off) + ; + for (i = 0; bad[i]; ++i) + if (!strncmp(path + off, bad[i], (int)(len - off))) + goto error; + i = snprintf(buf, size, "%.*s-glue", (int)len, path); + if (i == -1 || (size_t)i >= size) + goto error; + return buf; +error: + RTE_LOG(ERR, PMD, "unable to append \"-glue\" to last component of" + " RTE_EAL_PMD_PATH (\"" RTE_EAL_PMD_PATH "\"), please" + " re-configure DPDK"); + return NULL; +} + +static int +mlx5_glue_dlopen(void) +{ + char glue_path[sizeof(RTE_EAL_PMD_PATH) - 1 + sizeof("-glue")]; + void *handle = NULL; + + char const *path[] = { + /* + * A basic security check is necessary before trusting + * MLX5_GLUE_PATH, which may override RTE_EAL_PMD_PATH. + */ + (geteuid() == getuid() && getegid() == getgid() ? + getenv("MLX5_GLUE_PATH") : NULL), + /* + * When RTE_EAL_PMD_PATH is set, use its glue-suffixed + * variant, otherwise let dlopen() look up libraries on its + * own. + */ + (*RTE_EAL_PMD_PATH ? + mlx5_glue_path(glue_path, sizeof(glue_path)) : ""), + }; + unsigned int i = 0; + void **sym; + const char *dlmsg; + + while (!handle && i != RTE_DIM(path)) { + const char *end; + size_t len; + int ret; + + if (!path[i]) { + ++i; + continue; + } + end = strpbrk(path[i], ":;"); + if (!end) + end = path[i] + strlen(path[i]); + len = end - path[i]; + ret = 0; + do { + char name[ret + 1]; + + ret = snprintf(name, sizeof(name), "%.*s%s" MLX5_GLUE, + (int)len, path[i], + (!len || *(end - 1) == '/') ? "" : "/"); + if (ret == -1) + break; + if (sizeof(name) != (size_t)ret + 1) + continue; + DRV_LOG(DEBUG, "Looking for rdma-core glue as " + "\"%s\"", name); + handle = dlopen(name, RTLD_LAZY); + break; + } while (1); + path[i] = end + 1; + if (!*end) + ++i; + } + if (!handle) { + rte_errno = EINVAL; + dlmsg = dlerror(); + if (dlmsg) + DRV_LOG(WARNING, "Cannot load glue library: %s", dlmsg); + goto glue_error; + } + sym = dlsym(handle, "mlx5_glue"); + if (!sym || !*sym) { + rte_errno = EINVAL; + dlmsg = dlerror(); + if (dlmsg) + DRV_LOG(ERR, "Cannot resolve glue symbol: %s", dlmsg); + goto glue_error; + } + mlx5_glue = *sym; + return 0; + +glue_error: + if (handle) + dlclose(handle); + return -1; +} + +#endif + +/** + * Initialization routine for run-time dependency on rdma-core. + */ +void +mlx5_glue_constructor(void) +{ + /* + * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use + * huge pages. Calling ibv_fork_init() during init allows + * applications to use fork() safely for purposes other than + * using this PMD, which is not supported in forked processes. + */ + setenv("RDMAV_HUGEPAGES_SAFE", "1", 1); + /* Match the size of Rx completion entry to the size of a cacheline. */ + if (RTE_CACHE_LINE_SIZE == 128) + setenv("MLX5_CQE_SIZE", "128", 0); + /* + * MLX5_DEVICE_FATAL_CLEANUP tells ibv_destroy functions to + * cleanup all the Verbs resources even when the device was removed. + */ + setenv("MLX5_DEVICE_FATAL_CLEANUP", "1", 1); + +#ifdef MLX5_GLUE + if (mlx5_glue_dlopen() != 0) + goto glue_error; +#endif + +#ifdef RTE_LIBRTE_MLX5_DEBUG + /* Glue structure must not contain any NULL pointers. */ + { + unsigned int i; + + for (i = 0; i != sizeof(*mlx5_glue) / sizeof(void *); ++i) + MLX5_ASSERT(((const void *const *)mlx5_glue)[i]); + } +#endif + if (strcmp(mlx5_glue->version, MLX5_GLUE_VERSION)) { + rte_errno = EINVAL; + DRV_LOG(ERR, "rdma-core glue \"%s\" mismatch: \"%s\" is " + "required", mlx5_glue->version, MLX5_GLUE_VERSION); + goto glue_error; + } + mlx5_glue->fork_init(); + return; + +glue_error: + DRV_LOG(WARNING, "Cannot initialize MLX5 common due to missing" + " run-time dependency on rdma-core libraries (libibverbs," + " libmlx5)"); + mlx5_glue = NULL; +} diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c index 1c77763..db94d4a 100644 --- a/drivers/common/mlx5/mlx5_common.c +++ b/drivers/common/mlx5/mlx5_common.c @@ -5,16 +5,11 @@ #include #include #include -#ifdef RTE_IBVERBS_LINK_DLOPEN -#include -#endif #include #include "mlx5_common.h" #include "mlx5_common_utils.h" -#include "mlx5_glue.h" - int mlx5_common_logtype; @@ -24,58 +19,6 @@ const struct mlx5_glue *mlx5_glue; uint8_t haswell_broadwell_cpu; -/** - * Get PCI information by sysfs device path. - * - * @param dev_path - * Pointer to device sysfs folder name. - * @param[out] pci_addr - * PCI bus address output buffer. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_dev_to_pci_addr(const char *dev_path, - struct rte_pci_addr *pci_addr) -{ - FILE *file; - char line[32]; - MKSTR(path, "%s/device/uevent", dev_path); - - file = fopen(path, "rb"); - if (file == NULL) { - rte_errno = errno; - return -rte_errno; - } - while (fgets(line, sizeof(line), file) == line) { - size_t len = strlen(line); - int ret; - - /* Truncate long lines. */ - if (len == (sizeof(line) - 1)) - while (line[(len - 1)] != '\n') { - ret = fgetc(file); - if (ret == EOF) - break; - line[(len - 1)] = ret; - } - /* Extract information. */ - if (sscanf(line, - "PCI_SLOT_NAME=" - "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n", - &pci_addr->domain, - &pci_addr->bus, - &pci_addr->devid, - &pci_addr->function) == 4) { - ret = 0; - break; - } - } - fclose(file); - return 0; -} - static int mlx5_class_check_handler(__rte_unused const char *key, const char *value, void *opaque) @@ -112,187 +55,6 @@ mlx5_class_get(struct rte_devargs *devargs) return ret; } -/** - * Extract port name, as a number, from sysfs or netlink information. - * - * @param[in] port_name_in - * String representing the port name. - * @param[out] port_info_out - * Port information, including port name as a number and port name - * type if recognized - * - * @return - * port_name field set according to recognized name format. - */ -void -mlx5_translate_port_name(const char *port_name_in, - struct mlx5_switch_info *port_info_out) -{ - char pf_c1, pf_c2, vf_c1, vf_c2; - char *end; - int sc_items; - - /* - * Check for port-name as a string of the form pf0vf0 - * (support kernel ver >= 5.0 or OFED ver >= 4.6). - */ - sc_items = sscanf(port_name_in, "%c%c%d%c%c%d", - &pf_c1, &pf_c2, &port_info_out->pf_num, - &vf_c1, &vf_c2, &port_info_out->port_name); - if (sc_items == 6 && - pf_c1 == 'p' && pf_c2 == 'f' && - vf_c1 == 'v' && vf_c2 == 'f') { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_PFVF; - return; - } - /* - * Check for port-name as a string of the form p0 - * (support kernel ver >= 5.0, or OFED ver >= 4.6). - */ - sc_items = sscanf(port_name_in, "%c%d", - &pf_c1, &port_info_out->port_name); - if (sc_items == 2 && pf_c1 == 'p') { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK; - return; - } - /* Check for port-name as a number (support kernel ver < 5.0 */ - errno = 0; - port_info_out->port_name = strtol(port_name_in, &end, 0); - if (!errno && - (size_t)(end - port_name_in) == strlen(port_name_in)) { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_LEGACY; - return; - } - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; - return; -} - -#ifdef MLX5_GLUE - -/** - * Suffix RTE_EAL_PMD_PATH with "-glue". - * - * This function performs a sanity check on RTE_EAL_PMD_PATH before - * suffixing its last component. - * - * @param buf[out] - * Output buffer, should be large enough otherwise NULL is returned. - * @param size - * Size of @p out. - * - * @return - * Pointer to @p buf or @p NULL in case suffix cannot be appended. - */ -static char * -mlx5_glue_path(char *buf, size_t size) -{ - static const char *const bad[] = { "/", ".", "..", NULL }; - const char *path = RTE_EAL_PMD_PATH; - size_t len = strlen(path); - size_t off; - int i; - - while (len && path[len - 1] == '/') - --len; - for (off = len; off && path[off - 1] != '/'; --off) - ; - for (i = 0; bad[i]; ++i) - if (!strncmp(path + off, bad[i], (int)(len - off))) - goto error; - i = snprintf(buf, size, "%.*s-glue", (int)len, path); - if (i == -1 || (size_t)i >= size) - goto error; - return buf; -error: - RTE_LOG(ERR, PMD, "unable to append \"-glue\" to last component of" - " RTE_EAL_PMD_PATH (\"" RTE_EAL_PMD_PATH "\"), please" - " re-configure DPDK"); - return NULL; -} - -static int -mlx5_glue_dlopen(void) -{ - char glue_path[sizeof(RTE_EAL_PMD_PATH) - 1 + sizeof("-glue")]; - void *handle = NULL; - - const char *path[] = { - /* - * A basic security check is necessary before trusting - * MLX5_GLUE_PATH, which may override RTE_EAL_PMD_PATH. - */ - (geteuid() == getuid() && getegid() == getgid() ? - getenv("MLX5_GLUE_PATH") : NULL), - /* - * When RTE_EAL_PMD_PATH is set, use its glue-suffixed - * variant, otherwise let dlopen() look up libraries on its - * own. - */ - (*RTE_EAL_PMD_PATH ? - mlx5_glue_path(glue_path, sizeof(glue_path)) : ""), - }; - unsigned int i = 0; - void **sym; - const char *dlmsg; - - while (!handle && i != RTE_DIM(path)) { - const char *end; - size_t len; - int ret; - - if (!path[i]) { - ++i; - continue; - } - end = strpbrk(path[i], ":;"); - if (!end) - end = path[i] + strlen(path[i]); - len = end - path[i]; - ret = 0; - do { - char name[ret + 1]; - - ret = snprintf(name, sizeof(name), "%.*s%s" MLX5_GLUE, - (int)len, path[i], - (!len || *(end - 1) == '/') ? "" : "/"); - if (ret == -1) - break; - if (sizeof(name) != (size_t)ret + 1) - continue; - DRV_LOG(DEBUG, "Looking for rdma-core glue as " - "\"%s\"", name); - handle = dlopen(name, RTLD_LAZY); - break; - } while (1); - path[i] = end + 1; - if (!*end) - ++i; - } - if (!handle) { - rte_errno = EINVAL; - dlmsg = dlerror(); - if (dlmsg) - DRV_LOG(WARNING, "Cannot load glue library: %s", dlmsg); - goto glue_error; - } - sym = dlsym(handle, "mlx5_glue"); - if (!sym || !*sym) { - rte_errno = EINVAL; - dlmsg = dlerror(); - if (dlmsg) - DRV_LOG(ERR, "Cannot resolve glue symbol: %s", dlmsg); - goto glue_error; - } - mlx5_glue = *sym; - return 0; - -glue_error: - if (handle) - dlclose(handle); - return -1; -} - -#endif /* In case this is an x86_64 intel processor to check if * we should use relaxed ordering. @@ -325,55 +87,11 @@ RTE_INIT_PRIO(mlx5_log_init, LOG) } /** - * Initialization routine for run-time dependency on rdma-core. + * Initialization routine for run-time dependency on glue library. */ RTE_INIT_PRIO(mlx5_glue_init, CLASS) { - /* - * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use - * huge pages. Calling ibv_fork_init() during init allows - * applications to use fork() safely for purposes other than - * using this PMD, which is not supported in forked processes. - */ - setenv("RDMAV_HUGEPAGES_SAFE", "1", 1); - /* Match the size of Rx completion entry to the size of a cacheline. */ - if (RTE_CACHE_LINE_SIZE == 128) - setenv("MLX5_CQE_SIZE", "128", 0); - /* - * MLX5_DEVICE_FATAL_CLEANUP tells ibv_destroy functions to - * cleanup all the Verbs resources even when the device was removed. - */ - setenv("MLX5_DEVICE_FATAL_CLEANUP", "1", 1); - -#ifdef MLX5_GLUE - if (mlx5_glue_dlopen() != 0) - goto glue_error; -#endif - -#ifdef RTE_LIBRTE_MLX5_DEBUG - /* Glue structure must not contain any NULL pointers. */ - { - unsigned int i; - - for (i = 0; i != sizeof(*mlx5_glue) / sizeof(void *); ++i) - MLX5_ASSERT(((const void *const *)mlx5_glue)[i]); - } -#endif - if (strcmp(mlx5_glue->version, MLX5_GLUE_VERSION)) { - rte_errno = EINVAL; - DRV_LOG(ERR, "rdma-core glue \"%s\" mismatch: \"%s\" is " - "required", mlx5_glue->version, MLX5_GLUE_VERSION); - goto glue_error; - } - mlx5_glue->fork_init(); - return; - -glue_error: - DRV_LOG(WARNING, "Cannot initialize MLX5 common due to missing" - " run-time dependency on rdma-core libraries (libibverbs," - " libmlx5)"); - mlx5_glue = NULL; - return; + mlx5_glue_constructor(); } /** diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 8cd3ea5..8e679c6 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -212,6 +212,7 @@ enum mlx5_class mlx5_class_get(struct rte_devargs *devargs); __rte_internal void mlx5_translate_port_name(const char *port_name_in, struct mlx5_switch_info *port_info_out); +void mlx5_glue_constructor(void); extern uint8_t haswell_broadwell_cpu;