From patchwork Mon Oct 16 18:42:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Etelson X-Patchwork-Id: 132641 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6296243181; Mon, 16 Oct 2023 20:43:38 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B65AE40E03; Mon, 16 Oct 2023 20:43:26 +0200 (CEST) Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2045.outbound.protection.outlook.com [40.107.220.45]) by mails.dpdk.org (Postfix) with ESMTP id 0A4A540DDC for ; Mon, 16 Oct 2023 20:43:24 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HoCOggmOk2hSVnKkVvE9K7KZaBTD7u6mqXlqycbWbT+xL256WMN6EJpQXgDuojXuIA481vJ/+KUDEE2OEfu6aVV0B+miVHUXUB4QPq1RdOpPW1ztFV4wsBZ34kBfin0URVR7ISb93hkAR8Fq5QTv7YQf6K40V940AtbimAkeu3Mvh1CA8CwhG8EhJVEMFWzNFnTW1WtqigT7Ntk2/f+dZ5RjkEqYYyQfFl3B7VfNatRFHaPBrxrfFaakcZmb621AYOdljcA8AoBRK3n4mmUKURAMb5BlIodfDNC3wZ9yTVkjkoBv8hc97AFKxoFwBQTKKHOPIqe2F30OupRw48QVEA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3uIrSCtkjsh1atRkRJoBii1TcU7MgK5eZDMY/YDEVVc=; b=S69RXSeryEhMCvow2cmGfuHwu4Z6L2TRcaior6ibwG0BMo4eNOIERu3EAfWo1+EdDsgtKbevDy/8iP8ETertyj2UsG0MXIQB+Zdc+lVdmvIw+W0UGpuUFT9MGJEio4K0TnVBNCFg/mPZH8pVE69Bj2WnCGbOxpeY6q3pSBLGMgCiMuNvZVy8lThZNSyn5hUbJtVQPts9ENGyd+/0Qw8svwcye5SvHdZNWXX++rFj96EjFVFQpdxxzWvrfzXZEmcvoW4QyXp70rGJ/8EoBdtoNnwTAkGhvPUPyjB/GvexZ1ea73aoNmjtOpc66N7GNusxx+FaZYlj8z8305bsTEGiUw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3uIrSCtkjsh1atRkRJoBii1TcU7MgK5eZDMY/YDEVVc=; b=jhwapliXhInDm1P18PI/22vOo6sh1jZddNfMjB6yuPaRC4DyTBmvlgsSVVVbT83ZI0610goBPEBF3+OcBdhAU1GcBkqG773f5STGwAoxp2D6+nH4Ep/K4w483Cfd7pbvEFuWDGqvq+g6v0VHZE093t32XbWxlr4JL05CaqP4qQv9JC/3ZM4LGQ+TN84smCZj5twohNUHey6IiKCw7TJqN+i9NfaCBHonmKK+7d+SnBdc88NTXsaj4LUJmaxNHjpjjmnZNC5D+q4QpKZP9zVtiuc+N7tPZ4kkGTvbBayqKD7mjg/weCKbRV3d8iK8Jjg6S9A8vnuJ9xMEc+0a9+u6Vg== Received: from PA7P264CA0120.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:34c::18) by PH0PR12MB8776.namprd12.prod.outlook.com (2603:10b6:510:26f::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6886.35; Mon, 16 Oct 2023 18:43:21 +0000 Received: from SN1PEPF00026367.namprd02.prod.outlook.com (2603:10a6:102:34c:cafe::f2) by PA7P264CA0120.outlook.office365.com (2603:10a6:102:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6886.27 via Frontend Transport; Mon, 16 Oct 2023 18:43:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by SN1PEPF00026367.mail.protection.outlook.com (10.167.241.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6838.22 via Frontend Transport; Mon, 16 Oct 2023 18:43:19 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Mon, 16 Oct 2023 11:43:02 -0700 Received: from nvidia.com (10.126.230.35) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Mon, 16 Oct 2023 11:42:58 -0700 From: Gregory Etelson To: CC: , =?utf-8?b?wqA=?= , =?utf-8?q?=C2=A0_=2E_=2E_/patches/upstream-pmd-indirect-actions-list/v2/v2-?= =?utf-8?q?0000-cover-letter_=2E_patch?= , Shun Hao , Alex Vesker , Matan Azrad , Viacheslav Ovsiienko , Ori Kam , Suanming Mou Subject: [PATCH v2 04/16] net/mlx5/hws: add support for mirroring Date: Mon, 16 Oct 2023 21:42:23 +0300 Message-ID: <20231016184235.200427-4-getelson@nvidia.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231016184235.200427-1-getelson@nvidia.com> References: <20230927191046.405282-1-getelson@nvidia.com> <20231016184235.200427-1-getelson@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.126.230.35] X-ClientProxiedBy: rnnvmail202.nvidia.com (10.129.68.7) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF00026367:EE_|PH0PR12MB8776:EE_ X-MS-Office365-Filtering-Correlation-Id: 9cf43b8a-c30e-4544-dd17-08dbce77c452 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wivMlxKQBIWnqgDFnTx7zlijUp/rRsCSYjPgrtfU6RrQL9BEU2CKJz9a7N7Eql3SWWyEBnmjxY/3hGJ8paLAMNVOR7HzgI0A9YvkopAkZDq7D0FxILDzUROGv66XvH36y6zVohAxBcQ0XrsL5Al5QNWlOHevkabVM0eTTZ5xsBlNraLWtx9I9aWlSkOyYD32lA533ho362oBaScOReJbWI/Dbm/bzmX2YbahpBtrR8YhoDOm26OeZTGugYtpHT67ND7KOm7G043pvnWUrWwgdCgwNJPWYodjqz1WGV4gVO2sfU0lUSv95PW3hPiTazv7imA1bxfhkGLu7INobWb1guhEZ2Sm3FDKHt6tZ18c7Nt0e0RThJrU3grszBKP9EHAz8lIm97VGuYAieK5pMeSF8/IRvpa9F2fBnHBpx++mTHcqJHWa46ImBvrvOMa9YwU0wk990SiRolHSXZtCrJMjECPqCbfKjgepAj+3UWueEThrj6rcmfmnE59UXsWCwhMF3zDRzRHMkkKLNAFgwj1TPOvTuHEXcAGZDIaVBEEPwWiT9lwRsoYf5cPYHU/RSZTHmaUjc0V4OF4QSjt8X4EaKNr+vszHDHOfsV0jNxa5KCE0ihL0NtCER/f+inmBGpKE8yDcHuv5fAlI4xC9pZEX2Oi9jtOaNFZedmmWShmSwUZXtibRdPivcFfeh+5mIBHPUgCvXcUT5I9M7jO6vkfy6TaUKVrb55rGnvi8PyEw5ZZMf/KA3MCzhovkJkvP30/ X-Forefront-Antispam-Report: CIP:216.228.117.161; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge2.nvidia.com; CAT:NONE; SFS:(13230031)(4636009)(136003)(396003)(376002)(346002)(39860400002)(230922051799003)(1800799009)(186009)(82310400011)(64100799003)(451199024)(40470700004)(46966006)(36840700001)(70586007)(70206006)(2616005)(6916009)(54906003)(316002)(478600001)(107886003)(426003)(1076003)(336012)(26005)(7696005)(2906002)(6286002)(16526019)(5660300002)(4326008)(8936002)(8676002)(41300700001)(30864003)(86362001)(7636003)(36756003)(82740400003)(356005)(47076005)(83380400001)(6666004)(36860700001)(40480700001)(40460700003)(55016003); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2023 18:43:19.1845 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9cf43b8a-c30e-4544-dd17-08dbce77c452 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.161]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF00026367.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB8776 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Shun Hao This patch supports mirroring by adding an dest_array action. The action accecpts a list containing multiple destination actions, and can duplicate packet and forward to each destination in the list. Signed-off-by: Shun Hao Acked-by: Alex Vesker --- drivers/common/mlx5/mlx5_prm.h | 23 ++++- drivers/net/mlx5/hws/mlx5dr.h | 34 +++++++ drivers/net/mlx5/hws/mlx5dr_action.c | 130 ++++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_action.h | 3 + drivers/net/mlx5/hws/mlx5dr_cmd.c | 64 ++++++++++--- drivers/net/mlx5/hws/mlx5dr_cmd.h | 21 ++++- drivers/net/mlx5/hws/mlx5dr_debug.c | 1 + drivers/net/mlx5/hws/mlx5dr_table.c | 7 +- 8 files changed, 262 insertions(+), 21 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index df621b19af..aa0b622ca2 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -2320,7 +2320,11 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { }; struct mlx5_ifc_esw_cap_bits { - u8 reserved_at_0[0x60]; + u8 reserved_at_0[0x1d]; + u8 merged_eswitch[0x1]; + u8 reserved_at_1e[0x2]; + + u8 reserved_at_20[0x40]; u8 esw_manager_vport_number_valid[0x1]; u8 reserved_at_61[0xf]; @@ -5045,6 +5049,7 @@ struct mlx5_ifc_query_flow_table_out_bits { enum mlx5_flow_destination_type { MLX5_FLOW_DESTINATION_TYPE_VPORT = 0x0, MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1, + MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2, }; enum mlx5_flow_context_action { @@ -5088,6 +5093,19 @@ union mlx5_ifc_dest_format_flow_counter_list_auto_bits { u8 reserved_at_0[0x40]; }; +struct mlx5_ifc_extended_dest_format_bits { + struct mlx5_ifc_dest_format_bits destination_entry; + + u8 packet_reformat_id[0x20]; + + u8 reserved_at_60[0x20]; +}; + +#define MLX5_IFC_MULTI_PATH_FT_MAX_LEVEL 64 + +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif struct mlx5_ifc_flow_context_bits { u8 reserved_at_00[0x20]; u8 group_id[0x20]; @@ -5106,8 +5124,7 @@ struct mlx5_ifc_flow_context_bits { u8 reserved_at_e0[0x40]; u8 encrypt_decrypt_obj_id[0x20]; u8 reserved_at_140[0x16c0]; - /* Currently only one destnation */ - union mlx5_ifc_dest_format_flow_counter_list_auto_bits destination[1]; + union mlx5_ifc_dest_format_flow_counter_list_auto_bits destination[0]; }; struct mlx5_ifc_set_fte_in_bits { diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h index ea8bf683f3..1995c55132 100644 --- a/drivers/net/mlx5/hws/mlx5dr.h +++ b/drivers/net/mlx5/hws/mlx5dr.h @@ -46,6 +46,7 @@ enum mlx5dr_action_type { MLX5DR_ACTION_TYP_ASO_METER, MLX5DR_ACTION_TYP_ASO_CT, MLX5DR_ACTION_TYP_DEST_ROOT, + MLX5DR_ACTION_TYP_DEST_ARRAY, MLX5DR_ACTION_TYP_MAX, }; @@ -213,6 +214,20 @@ struct mlx5dr_rule_action { }; }; +struct mlx5dr_action_dest_attr { + /* Required action combination */ + enum mlx5dr_action_type *action_type; + + /* Required destination action to forward the packet */ + struct mlx5dr_action *dest; + + /* Optional reformat data */ + struct { + size_t reformat_data_sz; + void *reformat_data; + } reformat; +}; + /* Open a context used for direct rule insertion using hardware steering. * Each context can contain multiple tables of different types. * @@ -616,6 +631,25 @@ mlx5dr_action_create_pop_vlan(struct mlx5dr_context *ctx, uint32_t flags); struct mlx5dr_action * mlx5dr_action_create_push_vlan(struct mlx5dr_context *ctx, uint32_t flags); +/* Create a dest array action, this action can duplicate packets and forward to + * multiple destinations in the destination list. + * @param[in] ctx + * The context in which the new action will be created. + * @param[in] num_dest + * The number of dests attributes. + * @param[in] dests + * The destination array. Each contains a destination action and can have + * additional actions. + * @param[in] flags + * Action creation flags. (enum mlx5dr_action_flags) + * @return pointer to mlx5dr_action on success NULL otherwise. + */ +struct mlx5dr_action * +mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx, + size_t num_dest, + struct mlx5dr_action_dest_attr *dests, + uint32_t flags); + /* Create dest root table, this action will jump to root table according * the given priority. * @param[in] ctx diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c index 55ec4f71c9..f068bc7e9c 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.c +++ b/drivers/net/mlx5/hws/mlx5dr_action.c @@ -34,7 +34,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_ BIT(MLX5DR_ACTION_TYP_MISS) | BIT(MLX5DR_ACTION_TYP_TIR) | BIT(MLX5DR_ACTION_TYP_DROP) | - BIT(MLX5DR_ACTION_TYP_DEST_ROOT), + BIT(MLX5DR_ACTION_TYP_DEST_ROOT) | + BIT(MLX5DR_ACTION_TYP_DEST_ARRAY), BIT(MLX5DR_ACTION_TYP_LAST), }, [MLX5DR_TABLE_TYPE_NIC_TX] = { @@ -71,7 +72,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_ BIT(MLX5DR_ACTION_TYP_MISS) | BIT(MLX5DR_ACTION_TYP_VPORT) | BIT(MLX5DR_ACTION_TYP_DROP) | - BIT(MLX5DR_ACTION_TYP_DEST_ROOT), + BIT(MLX5DR_ACTION_TYP_DEST_ROOT) | + BIT(MLX5DR_ACTION_TYP_DEST_ARRAY), BIT(MLX5DR_ACTION_TYP_LAST), }, }; @@ -535,6 +537,7 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action, } break; case MLX5DR_ACTION_TYP_TBL: + case MLX5DR_ACTION_TYP_DEST_ARRAY: attr->action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT; attr->action_offset = MLX5DR_ACTION_OFFSET_HIT; attr->dest_table_id = obj->id; @@ -1700,6 +1703,124 @@ mlx5dr_action_create_modify_header(struct mlx5dr_context *ctx, return NULL; } +struct mlx5dr_action * +mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx, + size_t num_dest, + struct mlx5dr_action_dest_attr *dests, + uint32_t flags) +{ + struct mlx5dr_cmd_set_fte_dest *dest_list = NULL; + struct mlx5dr_cmd_ft_create_attr ft_attr = {0}; + struct mlx5dr_cmd_set_fte_attr fte_attr = {0}; + struct mlx5dr_cmd_forward_tbl *fw_island; + enum mlx5dr_table_type table_type; + struct mlx5dr_action *action; + uint32_t i; + int ret; + + if (num_dest <= 1) { + rte_errno = EINVAL; + DR_LOG(ERR, "Action must have multiple dests"); + return NULL; + } + + if (flags == (MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_SHARED)) { + ft_attr.type = FS_FT_NIC_RX; + ft_attr.level = MLX5_IFC_MULTI_PATH_FT_MAX_LEVEL - 1; + table_type = MLX5DR_TABLE_TYPE_NIC_RX; + } else if (flags == (MLX5DR_ACTION_FLAG_HWS_FDB | MLX5DR_ACTION_FLAG_SHARED)) { + ft_attr.type = FS_FT_FDB; + ft_attr.level = ctx->caps->fdb_ft.max_level - 1; + table_type = MLX5DR_TABLE_TYPE_FDB; + } else { + DR_LOG(ERR, "Action flags not supported"); + rte_errno = ENOTSUP; + return NULL; + } + + if (mlx5dr_context_shared_gvmi_used(ctx)) { + DR_LOG(ERR, "Cannot use this action in shared GVMI context"); + rte_errno = ENOTSUP; + return NULL; + } + + dest_list = simple_calloc(num_dest, sizeof(*dest_list)); + if (!dest_list) { + DR_LOG(ERR, "Failed to allocate memory for destinations"); + rte_errno = ENOMEM; + return NULL; + } + + for (i = 0; i < num_dest; i++) { + enum mlx5dr_action_type *action_type = dests[i].action_type; + + if (!mlx5dr_action_check_combo(dests[i].action_type, table_type)) { + DR_LOG(ERR, "Invalid combination of actions"); + rte_errno = EINVAL; + goto free_dest_list; + } + + for (; *action_type != MLX5DR_ACTION_TYP_LAST; action_type++) { + switch (*action_type) { + case MLX5DR_ACTION_TYP_TBL: + dest_list[i].destination_type = + MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; + dest_list[i].destination_id = dests[i].dest->devx_dest.devx_obj->id; + fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; + fte_attr.ignore_flow_level = 1; + break; + case MLX5DR_ACTION_TYP_VPORT: + dest_list[i].destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT; + dest_list[i].destination_id = dests[i].dest->vport.vport_num; + fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; + if (ctx->caps->merged_eswitch) { + dest_list[i].ext_flags |= + MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID; + dest_list[i].esw_owner_vhca_id = + dests[i].dest->vport.esw_owner_vhca_id; + } + break; + case MLX5DR_ACTION_TYP_TIR: + dest_list[i].destination_type = MLX5_FLOW_DESTINATION_TYPE_TIR; + dest_list[i].destination_id = dests[i].dest->devx_dest.devx_obj->id; + fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; + break; + default: + DR_LOG(ERR, "Unsupported action in dest_array"); + rte_errno = ENOTSUP; + goto free_dest_list; + } + } + } + fte_attr.dests_num = num_dest; + fte_attr.dests = dest_list; + + fw_island = mlx5dr_cmd_forward_tbl_create(ctx->ibv_ctx, &ft_attr, &fte_attr); + if (!fw_island) + goto free_dest_list; + + action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_DEST_ARRAY); + if (!action) + goto destroy_fw_island; + + ret = mlx5dr_action_create_stcs(action, fw_island->ft); + if (ret) + goto free_action; + + action->dest_array.fw_island = fw_island; + + simple_free(dest_list); + return action; + +free_action: + simple_free(action); +destroy_fw_island: + mlx5dr_cmd_forward_tbl_destroy(fw_island); +free_dest_list: + simple_free(dest_list); + return NULL; +} + struct mlx5dr_action * mlx5dr_action_create_dest_root(struct mlx5dr_context *ctx, uint16_t priority, @@ -1782,6 +1903,10 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action) mlx5dr_action_destroy_stcs(action); mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_POP); break; + case MLX5DR_ACTION_TYP_DEST_ARRAY: + mlx5dr_action_destroy_stcs(action); + mlx5dr_cmd_forward_tbl_destroy(action->dest_array.fw_island); + break; case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2: case MLX5DR_ACTION_TYP_MODIFY_HDR: for (i = 0; i < action->modify_header.num_of_patterns; i++) { @@ -2291,6 +2416,7 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at) case MLX5DR_ACTION_TYP_TIR: case MLX5DR_ACTION_TYP_TBL: case MLX5DR_ACTION_TYP_DEST_ROOT: + case MLX5DR_ACTION_TYP_DEST_ARRAY: case MLX5DR_ACTION_TYP_VPORT: case MLX5DR_ACTION_TYP_MISS: /* Hit action */ diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h index 104c6880c1..efe07c9d47 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.h +++ b/drivers/net/mlx5/hws/mlx5dr_action.h @@ -151,6 +151,9 @@ struct mlx5dr_action { struct { struct mlx5dr_devx_obj *devx_obj; } devx_dest; + struct { + struct mlx5dr_cmd_forward_tbl *fw_island; + } dest_array; }; }; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 8f407f9bce..22f7c6b019 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -158,18 +158,31 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx, uint32_t group_id, struct mlx5dr_cmd_set_fte_attr *fte_attr) { - uint32_t in[MLX5_ST_SZ_DW(set_fte_in) + MLX5_ST_SZ_DW(dest_format)] = {0}; uint32_t out[MLX5_ST_SZ_DW(set_fte_out)] = {0}; struct mlx5dr_devx_obj *devx_obj; + uint32_t dest_entry_sz; + uint32_t total_dest_sz; void *in_flow_context; uint32_t action_flags; - void *in_dests; + uint8_t *in_dests; + uint32_t inlen; + uint32_t *in; + uint32_t i; + + dest_entry_sz = MLX5_ST_SZ_BYTES(dest_format); + total_dest_sz = dest_entry_sz * fte_attr->dests_num; + inlen = align((MLX5_ST_SZ_BYTES(set_fte_in) + total_dest_sz), DW_SIZE); + in = simple_calloc(1, inlen); + if (!in) { + rte_errno = ENOMEM; + return NULL; + } devx_obj = simple_malloc(sizeof(*devx_obj)); if (!devx_obj) { DR_LOG(ERR, "Failed to allocate memory for fte object"); rte_errno = ENOMEM; - return NULL; + goto free_in; } MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); @@ -179,6 +192,7 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx, in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); MLX5_SET(flow_context, in_flow_context, group_id, group_id); MLX5_SET(flow_context, in_flow_context, flow_source, fte_attr->flow_source); + MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level); action_flags = fte_attr->action_flags; MLX5_SET(flow_context, in_flow_context, action, action_flags); @@ -195,15 +209,39 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx, } if (action_flags & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { - /* Only destination_list_size of size 1 is supported */ - MLX5_SET(flow_context, in_flow_context, destination_list_size, 1); - in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); - MLX5_SET(dest_format, in_dests, destination_type, fte_attr->destination_type); - MLX5_SET(dest_format, in_dests, destination_id, fte_attr->destination_id); - MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level); + in_dests = (uint8_t *)MLX5_ADDR_OF(flow_context, in_flow_context, destination); + + for (i = 0; i < fte_attr->dests_num; i++) { + struct mlx5dr_cmd_set_fte_dest *dest = &fte_attr->dests[i]; + + switch (dest->destination_type) { + case MLX5_FLOW_DESTINATION_TYPE_VPORT: + if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID) { + MLX5_SET(dest_format, in_dests, + destination_eswitch_owner_vhca_id_valid, 1); + MLX5_SET(dest_format, in_dests, + destination_eswitch_owner_vhca_id, + dest->esw_owner_vhca_id); + } + /* Fall through */ + case MLX5_FLOW_DESTINATION_TYPE_TIR: + case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: + MLX5_SET(dest_format, in_dests, destination_type, + dest->destination_type); + MLX5_SET(dest_format, in_dests, destination_id, + dest->destination_id); + break; + default: + rte_errno = EOPNOTSUPP; + goto free_devx; + } + + in_dests = in_dests + dest_entry_sz; + } + MLX5_SET(flow_context, in_flow_context, destination_list_size, fte_attr->dests_num); } - devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); + devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out)); if (!devx_obj->obj) { DR_LOG(ERR, "Failed to create FTE (syndrome: %#x)", mlx5dr_cmd_get_syndrome(out)); @@ -211,10 +249,13 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx, goto free_devx; } + simple_free(in); return devx_obj; free_devx: simple_free(devx_obj); +free_in: + simple_free(in); return NULL; } @@ -1244,6 +1285,9 @@ int mlx5dr_cmd_query_caps(struct ibv_context *ctx, caps->eswitch_manager_vport_number = MLX5_GET(query_hca_cap_out, out, capability.esw_cap.esw_manager_vport_number); + + caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out, + capability.esw_cap.merged_eswitch); } ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index bf3a362300..6f4aa3e320 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -5,15 +5,27 @@ #ifndef MLX5DR_CMD_H_ #define MLX5DR_CMD_H_ +enum mlx5dr_cmd_ext_dest_flags { + MLX5DR_CMD_EXT_DEST_REFORMAT = 1 << 0, + MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID = 1 << 1, +}; + +struct mlx5dr_cmd_set_fte_dest { + uint8_t destination_type; + uint32_t destination_id; + enum mlx5dr_cmd_ext_dest_flags ext_flags; + uint16_t esw_owner_vhca_id; +}; + struct mlx5dr_cmd_set_fte_attr { uint32_t action_flags; + uint8_t ignore_flow_level; + uint8_t flow_source; uint8_t encrypt_decrypt_type; uint32_t encrypt_decrypt_obj_id; uint32_t packet_reformat_id; - uint8_t destination_type; - uint32_t destination_id; - uint8_t ignore_flow_level; - uint8_t flow_source; + uint32_t dests_num; + struct mlx5dr_cmd_set_fte_dest *dests; }; struct mlx5dr_cmd_ft_create_attr { @@ -216,6 +228,7 @@ struct mlx5dr_cmd_query_caps { struct mlx5dr_cmd_query_ft_caps nic_ft; struct mlx5dr_cmd_query_ft_caps fdb_ft; bool eswitch_manager; + uint8_t merged_eswitch; uint32_t eswitch_manager_vport_number; uint8_t log_header_modify_argument_granularity; uint8_t log_header_modify_argument_max_alloc; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 89529944a3..e7b1f2cc32 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -23,6 +23,7 @@ const char *mlx5dr_debug_action_type_str[] = { [MLX5DR_ACTION_TYP_ASO_METER] = "ASO_METER", [MLX5DR_ACTION_TYP_ASO_CT] = "ASO_CT", [MLX5DR_ACTION_TYP_DEST_ROOT] = "DEST_ROOT", + [MLX5DR_ACTION_TYP_DEST_ARRAY] = "DEST_ARRAY", }; static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX, diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c index 91eb92db78..55b9b20150 100644 --- a/drivers/net/mlx5/hws/mlx5dr_table.c +++ b/drivers/net/mlx5/hws/mlx5dr_table.c @@ -22,6 +22,7 @@ mlx5dr_table_up_default_fdb_miss_tbl(struct mlx5dr_table *tbl) struct mlx5dr_cmd_ft_create_attr ft_attr = {0}; struct mlx5dr_cmd_set_fte_attr fte_attr = {0}; struct mlx5dr_cmd_forward_tbl *default_miss; + struct mlx5dr_cmd_set_fte_dest dest = {0}; struct mlx5dr_context *ctx = tbl->ctx; uint8_t tbl_type = tbl->type; @@ -37,9 +38,11 @@ mlx5dr_table_up_default_fdb_miss_tbl(struct mlx5dr_table *tbl) ft_attr.level = tbl->ctx->caps->fdb_ft.max_level; /* The last level */ ft_attr.rtc_valid = false; + dest.destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT; + dest.destination_id = ctx->caps->eswitch_manager_vport_number; fte_attr.action_flags = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; - fte_attr.destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT; - fte_attr.destination_id = ctx->caps->eswitch_manager_vport_number; + fte_attr.dests_num = 1; + fte_attr.dests = &dest; default_miss = mlx5dr_cmd_forward_tbl_create(mlx5dr_context_get_local_ibv(ctx), &ft_attr, &fte_attr);