From patchwork Thu Feb 24 13:40:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suanming Mou X-Patchwork-Id: 108273 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 E1CC4A034E; Thu, 24 Feb 2022 14:41:38 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 91C30426F6; Thu, 24 Feb 2022 14:41:36 +0100 (CET) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2084.outbound.protection.outlook.com [40.107.237.84]) by mails.dpdk.org (Postfix) with ESMTP id 61B854114D for ; Thu, 24 Feb 2022 14:41:32 +0100 (CET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M+6kjuL58VUIh5sizcgwvPnlPliAFlxnaB4n07jOm9Ax3kL+8mDzEAPMWRWPGjamI6Mgdsn9NAZm4ffqqUQAugF1Hail3+J9ZXhS8Q+9kc/rSzGsL7FC9nxrKl0olpAwJCdpacsUII9rj+Pqi6WkpII8yntJ8wY0pFM1Qky3wGAmjUphauPuRhxfTS9kkGS4Uu/1wvSMoEfdE62khULLjhpNQ3cG2I6WxZpHzd1d0DfX9+OEaz4hxeCBM90IFv+9/6vw2tsTRXl8i1LqJcsYYbV0EYUwXex8IdZxPtFfh0OSBqwj/Y6k8xFwbu9u1FsITbHvEPGjbYgfjUvgAKfqEA== 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=WxHNtFYvSoKjEwikx4F3je4gXXW7mAWPUe2W0MiVCz8=; b=Lzw6HEHbQ2pADMQGD744XU2rxGc6luv7dFkQ/pqVOrXYI8cSnkcAt4BG0LJ07Js8Idv5KP5NunI7v8SmIpurAS9fjxQnHwkWw8fTrrENDT8qHvitgQ3udn4wQlNAssgXx/A5vaE2ircoQm6Tr1h/1XkT9aFX/TPoJ4Uhnn4nL0DiBs9WFnUrJdxPq/DNcAQ0Hvcr8GOmrF4RXvRjxkLsOI4bpvlqpC1fqICQMZ52ZEguEEzcapQBS6Ogp3nB3PuRgdBgSC8ohfHFKcgP6JLJag5GsO8jGhAOTogVlIUBvxPb6WEkxMGdcusqW3vWi2KCvtoS0Hroq3K3EpY0mCCo0A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 12.22.5.236) 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=WxHNtFYvSoKjEwikx4F3je4gXXW7mAWPUe2W0MiVCz8=; b=HDmjhA4zhIDSif25nMFhsUzvMXvw2YihUJQZ7Eg4E21i6k9zs9n+0gv4LyHtH5K52fiyvve4YLaGS8kqd5IXQKH98K7izc3CUt1r4IglstjFS0OHTi0/K3kxYQYUtr+hK8TpNuZZM4cgGuzq0yHVjErjCCD92i5sLhvtzKRmDPKoCldTv6+MUkkLqShackpI84LWi+mJjXIty71Etx402MUQ3r8Ah9+TZYyBcWMxmU/Guaw75d/oyrAZy+Nc2Iv+7Kok/ffhWnd9HlZdndX6FEXiKNEfdNtKSJWWff8iTSMZYMp+LTYPzbi0Yq2r4SZmFW2ItbLCQvRwSgpwdmhExw== Received: from MWHPR04CA0065.namprd04.prod.outlook.com (2603:10b6:300:6c::27) by DM6PR12MB3355.namprd12.prod.outlook.com (2603:10b6:5:115::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4995.16; Thu, 24 Feb 2022 13:41:30 +0000 Received: from CO1NAM11FT019.eop-nam11.prod.protection.outlook.com (2603:10b6:300:6c:cafe::e6) by MWHPR04CA0065.outlook.office365.com (2603:10b6:300:6c::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.22 via Frontend Transport; Thu, 24 Feb 2022 13:41:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 12.22.5.236) 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 12.22.5.236 as permitted sender) receiver=protection.outlook.com; client-ip=12.22.5.236; helo=mail.nvidia.com; Received: from mail.nvidia.com (12.22.5.236) by CO1NAM11FT019.mail.protection.outlook.com (10.13.175.57) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.5017.22 via Frontend Transport; Thu, 24 Feb 2022 13:41:30 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by DRHQMAIL109.nvidia.com (10.27.9.19) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Thu, 24 Feb 2022 13:41:18 +0000 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.9; Thu, 24 Feb 2022 05:41:17 -0800 From: Suanming Mou To: , CC: , , Subject: [PATCH v4 04/14] net/mlx5: add port flow configuration Date: Thu, 24 Feb 2022 15:40:41 +0200 Message-ID: <20220224134051.18167-5-suanmingm@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20220224134051.18167-1-suanmingm@nvidia.com> References: <20220210162926.20436-1-suanmingm@nvidia.com> <20220224134051.18167-1-suanmingm@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.126.230.35] X-ClientProxiedBy: rnnvmail203.nvidia.com (10.129.68.9) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 50ddabbc-051e-41ed-0877-08d9f79b5d02 X-MS-TrafficTypeDiagnostic: DM6PR12MB3355:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: b+cIDWFCz7QvBzfPzaClSXO+yMsKK0WZDK7Kmw5GhMhQFe/w5fRl18288b9Z5jUPF7G8vXosP2eMLyApdcj2gUxWn4hK6ptrLUV86L/na0bkbosXFCWb8NoGnR2XwmkvwtZerhNepr6WGaxEd5fsUFoReywLDztuYa8HebtcX8GpB+bLCbfh4qZoV9A5mOLyYFl2PxQhR+Ss7txogo8R7T3n+G0ZFyHeVJjNxJXsyCjE61e3FlzkciGIFsa2UNqUigp2CXJL3pIx+5IrTdnDWJ894b2dBBMyO1o9cO7ZjeYq6Vgi9qIkmZBi78EhfsRVoP4aq6tP51veabVxuYX6lsvdIhNHFddjQdZ3V1O+mDIlWVASzxHmB19T3gjpS1RVCVhmRzVK8n/e6V0vizX8gtyZm69m+CR9pHpti6FPnSq7Q87i0u0KeHoif+FMujA4haMyWfxTk4GDZqoYqiGiCycxKn0pkvs+S2HECBCCZoPmvP2ubazZju7iHFxR3xcrcfZI3pisjz6huIKowBVbnvquL2pGFrdYTzopvsyVX6HzNxkXHzJ2hQXZk3NfxpfVmiFqBcJG6/dc0JHx1hR7XV+FYKme+/AM6Pb6F7NUaHuyq/yaLIfuOsw266n+LtJYRsIBxwur1ZGP5KaXu6KyKoLdyL9VUTJsxZ2LgLJ11R9n/GvICdkVno5LHWjlERsq9NoL+ainvEFr13Q5ckLgB9PuRBfH07yf20E+9PZ+Qro= X-Forefront-Antispam-Report: CIP:12.22.5.236; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:mail.nvidia.com; PTR:InfoNoRecords; CAT:NONE; SFS:(13230001)(4636009)(36840700001)(46966006)(40470700004)(83380400001)(7696005)(36860700001)(8936002)(5660300002)(47076005)(508600001)(30864003)(82310400004)(110136005)(6666004)(4326008)(8676002)(336012)(70206006)(54906003)(316002)(2616005)(6636002)(26005)(16526019)(70586007)(2906002)(40460700003)(36756003)(1076003)(86362001)(426003)(55016003)(81166007)(356005)(186003)(6286002)(21314003)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Feb 2022 13:41:30.0635 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 50ddabbc-051e-41ed-0877-08d9f79b5d02 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[12.22.5.236]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT019.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3355 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 The hardware steering is backend to support rte_flow_async API in mlx5 PMD. The port configuration function creates the queues and needed flow management resources. The PMD layer configuration function allocates the queues' context and per-queue job descriptor pool. The job descriptor pool size is equal to the queue size, and the job descriptors will be popped from pool with LIFO strategy to convey the flow information during flow insertion/destruction. Then, while polling the queued operation result, the flow information will be extracted from the job descriptor and the descriptor will be pushed back to the LIFO pool. The commit creates the flow port queues and the job descriptor pools. Signed-off-by: Suanming Mou Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.c | 3 + drivers/net/mlx5/mlx5.h | 30 +++++- drivers/net/mlx5/mlx5_flow.c | 86 +++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 15 +++ drivers/net/mlx5/mlx5_flow_hw.c | 159 ++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index baa4ae75f3..24bbfee519 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1820,6 +1820,9 @@ mlx5_dev_close(struct rte_eth_dev *dev) /* Free the eCPRI flex parser resource. */ mlx5_flex_parser_ecpri_release(dev); mlx5_flex_item_port_cleanup(dev); +#if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H) + flow_hw_resource_release(dev); +#endif if (priv->rxq_privs != NULL) { /* XXX race condition if mlx5_rx_burst() is still running. */ rte_delay_us_sleep(1000); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index d36d679625..86c84d1510 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -33,7 +33,9 @@ #include "mlx5_utils.h" #include "mlx5_os.h" #include "mlx5_autoconf.h" - +#if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H) +#include "mlx5_dr.h" +#endif #define MLX5_SH(dev) (((struct mlx5_priv *)(dev)->data->dev_private)->sh) @@ -320,6 +322,26 @@ struct mlx5_lb_ctx { uint16_t refcnt; /* Reference count for representors. */ }; +/* HW steering queue job descriptor type. */ +enum { + MLX5_HW_Q_JOB_TYPE_CREATE, /* Flow create job type. */ + MLX5_HW_Q_JOB_TYPE_DESTROY, /* Flow destroy job type. */ +}; + +/* HW steering flow management job descriptor. */ +struct mlx5_hw_q_job { + uint32_t type; /* Job type. */ + struct rte_flow *flow; /* Flow attached to the job. */ + void *user_data; /* Job user data. */ +}; + +/* HW steering job descriptor LIFO pool. */ +struct mlx5_hw_q { + uint32_t job_idx; /* Free job index. */ + uint32_t size; /* LIFO size. */ + struct mlx5_hw_q_job **job; /* LIFO header. */ +} __rte_cache_aligned; + #define MLX5_COUNTERS_PER_POOL 512 #define MLX5_MAX_PENDING_QUERIES 4 #define MLX5_CNT_CONTAINER_RESIZE 64 @@ -1480,6 +1502,12 @@ struct mlx5_priv { struct mlx5_flex_item flex_item[MLX5_PORT_FLEX_ITEM_NUM]; /* Flex items have been created on the port. */ uint32_t flex_item_map; /* Map of allocated flex item elements. */ +#if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H) + struct mlx5dr_context *dr_ctx; /**< HW steering DR context. */ + uint32_t nb_queue; /* HW steering queue number. */ + /* HW steering queue polling mechanism job descriptor LIFO. */ + struct mlx5_hw_q *hw_q; +#endif }; #define PORT_ID(priv) ((priv)->dev_data->port_id) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index ef7f2ceaee..156fb35ce9 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -805,6 +805,17 @@ static int mlx5_flow_flex_item_release(struct rte_eth_dev *dev, const struct rte_flow_item_flex_handle *handle, struct rte_flow_error *error); +static int +mlx5_flow_info_get(struct rte_eth_dev *dev, + struct rte_flow_port_info *port_info, + struct rte_flow_queue_info *queue_info, + struct rte_flow_error *error); +static int +mlx5_flow_port_configure(struct rte_eth_dev *dev, + const struct rte_flow_port_attr *port_attr, + uint16_t nb_queue, + const struct rte_flow_queue_attr *queue_attr[], + struct rte_flow_error *err); static const struct rte_flow_ops mlx5_flow_ops = { .validate = mlx5_flow_validate, @@ -826,6 +837,8 @@ static const struct rte_flow_ops mlx5_flow_ops = { .get_restore_info = mlx5_flow_tunnel_get_restore_info, .flex_item_create = mlx5_flow_flex_item_create, .flex_item_release = mlx5_flow_flex_item_release, + .info_get = mlx5_flow_info_get, + .configure = mlx5_flow_port_configure, }; /* Tunnel information. */ @@ -3440,6 +3453,12 @@ flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr) if (type != MLX5_FLOW_TYPE_MAX) return type; + /* + * Currently when dv_flow_en == 2, only HW steering engine is + * supported. New engines can also be chosen here if ready. + */ + if (priv->sh->config.dv_flow_en == 2) + return MLX5_FLOW_TYPE_HW; /* If no OS specific type - continue with DV/VERBS selection */ if (attr->transfer && priv->sh->config.dv_esw_en) type = MLX5_FLOW_TYPE_DV; @@ -7847,6 +7866,73 @@ mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt, return -ENOTSUP; } +/** + * Get information about HWS pre-configurable resources. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[out] port_info + * Pointer to port information. + * @param[out] queue_info + * Pointer to queue information. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_info_get(struct rte_eth_dev *dev, + struct rte_flow_port_info *port_info, + struct rte_flow_queue_info *queue_info, + struct rte_flow_error *error) +{ + const struct mlx5_flow_driver_ops *fops; + + if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "info get with incorrect steering mode"); + fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW); + return fops->info_get(dev, port_info, queue_info, error); +} + +/** + * Configure port HWS resources. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] port_attr + * Port configuration attributes. + * @param[in] nb_queue + * Number of queue. + * @param[in] queue_attr + * Array that holds attributes for each flow queue. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_port_configure(struct rte_eth_dev *dev, + const struct rte_flow_port_attr *port_attr, + uint16_t nb_queue, + const struct rte_flow_queue_attr *queue_attr[], + struct rte_flow_error *error) +{ + const struct mlx5_flow_driver_ops *fops; + + if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "port configure with incorrect steering mode"); + fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW); + return fops->configure(dev, port_attr, nb_queue, queue_attr, error); +} + /** * Allocate a new memory for the counter values wrapped by all the needed * management. diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index b70ef0c1b8..9f0dc4bde7 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1257,6 +1257,17 @@ typedef int (*mlx5_flow_item_update_t) const struct rte_flow_item_flex_handle *handle, const struct rte_flow_item_flex_conf *conf, struct rte_flow_error *error); +typedef int (*mlx5_flow_info_get_t) + (struct rte_eth_dev *dev, + struct rte_flow_port_info *port_info, + struct rte_flow_queue_info *queue_info, + struct rte_flow_error *error); +typedef int (*mlx5_flow_port_configure_t) + (struct rte_eth_dev *dev, + const struct rte_flow_port_attr *port_attr, + uint16_t nb_queue, + const struct rte_flow_queue_attr *queue_attr[], + struct rte_flow_error *err); struct mlx5_flow_driver_ops { mlx5_flow_validate_t validate; @@ -1295,6 +1306,8 @@ struct mlx5_flow_driver_ops { mlx5_flow_item_create_t item_create; mlx5_flow_item_release_t item_release; mlx5_flow_item_update_t item_update; + mlx5_flow_info_get_t info_get; + mlx5_flow_port_configure_t configure; }; /* mlx5_flow.c */ @@ -1762,4 +1775,6 @@ const struct mlx5_flow_tunnel * mlx5_get_tof(const struct rte_flow_item *items, const struct rte_flow_action *actions, enum mlx5_tof_rule_type *rule_type); +void +flow_hw_resource_release(struct rte_eth_dev *dev); #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 729d5914a8..e5b2ae91d8 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -4,10 +4,169 @@ #include +#include +#include "mlx5_defs.h" #include "mlx5_flow.h" #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H) const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops; +/** + * Get information about HWS pre-configurable resources. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[out] port_info + * Pointer to port information. + * @param[out] queue_info + * Pointer to queue information. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_hw_info_get(struct rte_eth_dev *dev __rte_unused, + struct rte_flow_port_info *port_info __rte_unused, + struct rte_flow_queue_info *queue_info __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + /* Nothing to be updated currently. */ + memset(port_info, 0, sizeof(*port_info)); + /* Queue size is unlimited from low-level. */ + queue_info->max_size = UINT32_MAX; + return 0; +} + +/** + * Configure port HWS resources. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] port_attr + * Port configuration attributes. + * @param[in] nb_queue + * Number of queue. + * @param[in] queue_attr + * Array that holds attributes for each flow queue. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_hw_configure(struct rte_eth_dev *dev, + const struct rte_flow_port_attr *port_attr, + uint16_t nb_queue, + const struct rte_flow_queue_attr *queue_attr[], + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5dr_context *dr_ctx = NULL; + struct mlx5dr_context_attr dr_ctx_attr = {0}; + struct mlx5_hw_q *hw_q; + struct mlx5_hw_q_job *job = NULL; + uint32_t mem_size, i, j; + + if (!port_attr || !nb_queue || !queue_attr) { + rte_errno = EINVAL; + goto err; + } + /* In case re-configuring, release existing context at first. */ + if (priv->dr_ctx) { + /* */ + for (i = 0; i < nb_queue; i++) { + hw_q = &priv->hw_q[i]; + /* Make sure all queues are empty. */ + if (hw_q->size != hw_q->job_idx) { + rte_errno = EBUSY; + goto err; + } + } + flow_hw_resource_release(dev); + } + /* Allocate the queue job descriptor LIFO. */ + mem_size = sizeof(priv->hw_q[0]) * nb_queue; + for (i = 0; i < nb_queue; i++) { + /* + * Check if the queues' size are all the same as the + * limitation from HWS layer. + */ + if (queue_attr[i]->size != queue_attr[0]->size) { + rte_errno = EINVAL; + goto err; + } + mem_size += (sizeof(struct mlx5_hw_q_job *) + + sizeof(struct mlx5_hw_q_job)) * + queue_attr[0]->size; + } + priv->hw_q = mlx5_malloc(MLX5_MEM_ZERO, mem_size, + 64, SOCKET_ID_ANY); + if (!priv->hw_q) { + rte_errno = ENOMEM; + goto err; + } + for (i = 0; i < nb_queue; i++) { + priv->hw_q[i].job_idx = queue_attr[i]->size; + priv->hw_q[i].size = queue_attr[i]->size; + if (i == 0) + priv->hw_q[i].job = (struct mlx5_hw_q_job **) + &priv->hw_q[nb_queue]; + else + priv->hw_q[i].job = (struct mlx5_hw_q_job **) + &job[queue_attr[i - 1]->size]; + job = (struct mlx5_hw_q_job *) + &priv->hw_q[i].job[queue_attr[i]->size]; + for (j = 0; j < queue_attr[i]->size; j++) + priv->hw_q[i].job[j] = &job[j]; + } + dr_ctx_attr.pd = priv->sh->cdev->pd; + dr_ctx_attr.queues = nb_queue; + /* Queue size should all be the same. Take the first one. */ + dr_ctx_attr.queue_size = queue_attr[0]->size; + dr_ctx = mlx5dr_context_open(priv->sh->cdev->ctx, &dr_ctx_attr); + /* rte_errno has been updated by HWS layer. */ + if (!dr_ctx) + goto err; + priv->dr_ctx = dr_ctx; + priv->nb_queue = nb_queue; + return 0; +err: + if (dr_ctx) + claim_zero(mlx5dr_context_close(dr_ctx)); + mlx5_free(priv->hw_q); + priv->hw_q = NULL; + return rte_flow_error_set(error, rte_errno, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "fail to configure port"); +} + +/** + * Release HWS resources. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + */ +void +flow_hw_resource_release(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + + if (!priv->dr_ctx) + return; + mlx5_free(priv->hw_q); + priv->hw_q = NULL; + claim_zero(mlx5dr_context_close(priv->dr_ctx)); + priv->dr_ctx = NULL; + priv->nb_queue = 0; +} + +const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops = { + .info_get = flow_hw_info_get, + .configure = flow_hw_configure, +}; + #endif