Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/132404/?format=api
http://patches.dpdk.org/api/patches/132404/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230908160552.148060-4-yuying.zhang@intel.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20230908160552.148060-4-yuying.zhang@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20230908160552.148060-4-yuying.zhang@intel.com", "date": "2023-09-08T16:05:46", "name": "[v10,3/9] net/cpfl: set up flow offloading skeleton", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "2d6ea491857ffe9c5b326a2e284a0fb13473f74e", "submitter": { "id": 1844, "url": "http://patches.dpdk.org/api/people/1844/?format=api", "name": "Zhang, Yuying", "email": "yuying.zhang@intel.com" }, "delegate": { "id": 1540, "url": "http://patches.dpdk.org/api/users/1540/?format=api", "username": "qzhan15", "first_name": "Qi", "last_name": "Zhang", "email": "qi.z.zhang@intel.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230908160552.148060-4-yuying.zhang@intel.com/mbox/", "series": [ { "id": 29766, "url": "http://patches.dpdk.org/api/series/29766/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29766", "date": "2023-09-08T16:05:43", "name": "add rte flow support for cpfl", "version": 10, "mbox": "http://patches.dpdk.org/series/29766/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/132404/comments/", "check": "success", "checks": "http://patches.dpdk.org/api/patches/132404/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "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])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 96A7342338;\n\tMon, 9 Oct 2023 10:02:37 +0200 (CEST)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8B94E4067C;\n\tMon, 9 Oct 2023 10:02:21 +0200 (CEST)", "from mgamail.intel.com (mgamail.intel.com [134.134.136.126])\n by mails.dpdk.org (Postfix) with ESMTP id 4D5224067C\n for <dev@dpdk.org>; Mon, 9 Oct 2023 10:02:19 +0200 (CEST)", "from orsmga005.jf.intel.com ([10.7.209.41])\n by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 09 Oct 2023 01:02:18 -0700", "from dpdk-pengyuan-mev.sh.intel.com ([10.67.119.132])\n by orsmga005.jf.intel.com with ESMTP; 09 Oct 2023 01:02:16 -0700" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1696838539; x=1728374539;\n h=from:to:subject:date:message-id:in-reply-to:references:\n mime-version:content-transfer-encoding;\n bh=wvHs+GKuU8UCw4LTcwJG9oFLvsp94NElrqe3kIzWfLA=;\n b=Z0SLz3fLKlajeMixW1o+yctTLu6Jy/qh+qhR30n8BE6cOBPbK2YRvRzJ\n frDtXZDMTZBNkvV+o4DszAfh3zUPiJy0aE6jYPbHsS6svDkAzNRaeus5f\n t2diLU4ynt0zjI0aSD6E8OTEFh4mwccJ2BGmgs14tT0aZSwTqsE+VlUn6\n djzabFbZvke9L0Q7yWez9HYOQHM3pifU6IxEFfQFnkkIxpebV5uFMDwKg\n rsFu5j/Tsxhvr7Lp26OWa+/ToU+OwvpYohVz6awGRU9jOWCRltbReUsgF\n aL6ltL+OnEkqKMDTvx9nl/xviagWFMze6+z7Lsxlz35Yn4OZixvfI9XxW A==;", "X-IronPort-AV": [ "E=McAfee;i=\"6600,9927,10857\"; a=\"369155057\"", "E=Sophos;i=\"6.03,209,1694761200\"; d=\"scan'208\";a=\"369155057\"", "E=McAfee;i=\"6600,9927,10857\"; a=\"926675830\"", "E=Sophos;i=\"6.03,209,1694761200\"; d=\"scan'208\";a=\"926675830\"" ], "X-ExtLoop1": "1", "From": "\"Zhang, Yuying\" <yuying.zhang@intel.com>", "To": "yuying.zhang@intel.com, dev@dpdk.org, qi.z.zhang@intel.com,\n jingjing.wu@intel.com, beilei.xing@intel.com", "Subject": "[PATCH v10 3/9] net/cpfl: set up flow offloading skeleton", "Date": "Fri, 8 Sep 2023 16:05:46 +0000", "Message-Id": "<20230908160552.148060-4-yuying.zhang@intel.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20230908160552.148060-1-yuying.zhang@intel.com>", "References": "<20230928084458.2333663-1-yuying.zhang@intel.com>\n <20230908160552.148060-1-yuying.zhang@intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "From: Yuying Zhang <yuying.zhang@intel.com>\n\nSet up the rte_flow backend skeleton. Introduce the framework\nto support different engines as rte_flow backend. Bridge rte_flow\ndriver API to flow engines.\n\nSigned-off-by: Yuying Zhang <yuying.zhang@intel.com>\nAcked-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n drivers/net/cpfl/cpfl_ethdev.c | 53 ++++++\n drivers/net/cpfl/cpfl_ethdev.h | 5 +\n drivers/net/cpfl/cpfl_flow.c | 339 +++++++++++++++++++++++++++++++++\n drivers/net/cpfl/cpfl_flow.h | 85 +++++++++\n drivers/net/cpfl/meson.build | 1 +\n 5 files changed, 483 insertions(+)\n create mode 100644 drivers/net/cpfl/cpfl_flow.c\n create mode 100644 drivers/net/cpfl/cpfl_flow.h", "diff": "diff --git a/drivers/net/cpfl/cpfl_ethdev.c b/drivers/net/cpfl/cpfl_ethdev.c\nindex 1745f703c8..c350728861 100644\n--- a/drivers/net/cpfl/cpfl_ethdev.c\n+++ b/drivers/net/cpfl/cpfl_ethdev.c\n@@ -15,6 +15,7 @@\n #include \"cpfl_ethdev.h\"\n #include <ethdev_private.h>\n #include \"cpfl_rxtx.h\"\n+#include \"cpfl_flow.h\"\n \n #define CPFL_REPRESENTOR\t\"representor\"\n #define CPFL_TX_SINGLE_Q\t\"tx_single\"\n@@ -1074,6 +1075,19 @@ cpfl_dev_stop(struct rte_eth_dev *dev)\n \treturn 0;\n }\n \n+static void\n+cpfl_flow_free(struct cpfl_vport *vport)\n+{\n+\tstruct rte_flow *p_flow;\n+\n+\twhile ((p_flow = TAILQ_FIRST(&vport->itf.flow_list))) {\n+\t\tTAILQ_REMOVE(&vport->itf.flow_list, p_flow, next);\n+\t\tif (p_flow->engine->free)\n+\t\t\tp_flow->engine->free(p_flow);\n+\t\trte_free(p_flow);\n+\t}\n+}\n+\n static int\n cpfl_p2p_queue_grps_del(struct idpf_vport *vport)\n {\n@@ -1105,6 +1119,7 @@ cpfl_dev_close(struct rte_eth_dev *dev)\n \tif (!adapter->base.is_rx_singleq && !adapter->base.is_tx_singleq)\n \t\tcpfl_p2p_queue_grps_del(vport);\n \n+\tcpfl_flow_free(cpfl_vport);\n \tidpf_vport_deinit(vport);\n \trte_free(cpfl_vport->p2p_q_chunks_info);\n \n@@ -1117,6 +1132,29 @@ cpfl_dev_close(struct rte_eth_dev *dev)\n \treturn 0;\n }\n \n+static int\n+cpfl_dev_flow_ops_get(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_ops **ops)\n+{\n+\tstruct cpfl_itf *itf;\n+\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\titf = CPFL_DEV_TO_ITF(dev);\n+\n+\t/* only vport support rte_flow */\n+\tif (itf->type != CPFL_ITF_TYPE_VPORT)\n+\t\treturn -ENOTSUP;\n+#ifdef RTE_HAS_JANSSON\n+\t*ops = &cpfl_flow_ops;\n+#else\n+\t*ops = NULL;\n+\tPMD_DRV_LOG(NOTICE, \"not support rte_flow, please install json-c library.\");\n+#endif\n+\treturn 0;\n+}\n+\n static int\n cpfl_hairpin_get_peer_ports(struct rte_eth_dev *dev, uint16_t *peer_ports,\n \t\t\t size_t len, uint32_t tx)\n@@ -1318,6 +1356,7 @@ static const struct eth_dev_ops cpfl_eth_dev_ops = {\n \t.xstats_get\t\t\t= cpfl_dev_xstats_get,\n \t.xstats_get_names\t\t= cpfl_dev_xstats_get_names,\n \t.xstats_reset\t\t\t= cpfl_dev_xstats_reset,\n+\t.flow_ops_get\t\t\t= cpfl_dev_flow_ops_get,\n \t.hairpin_cap_get\t\t= cpfl_hairpin_cap_get,\n \t.rx_hairpin_queue_setup\t\t= cpfl_rx_hairpin_queue_setup,\n \t.tx_hairpin_queue_setup\t\t= cpfl_tx_hairpin_queue_setup,\n@@ -2021,6 +2060,13 @@ cpfl_adapter_ext_init(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *a\n \t\tgoto err_vports_alloc;\n \t}\n \n+#ifdef RTE_HAS_JANSSON\n+\tret = cpfl_flow_init(adapter);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to init flow module\");\n+\t\tgoto err_flow_init;\n+\t}\n+#endif\n \tadapter->cur_vports = 0;\n \tadapter->cur_vport_nb = 0;\n \n@@ -2028,6 +2074,9 @@ cpfl_adapter_ext_init(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *a\n \n \treturn ret;\n \n+#ifdef RTE_HAS_JANSSON\n+err_flow_init:\n+#endif\n err_vports_alloc:\n \trte_eal_alarm_cancel(cpfl_dev_alarm_handler, adapter);\n \tcpfl_repr_allowlist_uninit(adapter);\n@@ -2182,6 +2231,7 @@ cpfl_dev_vport_init(struct rte_eth_dev *dev, void *init_params)\n \tcpfl_vport->itf.type = CPFL_ITF_TYPE_VPORT;\n \tcpfl_vport->itf.adapter = adapter;\n \tcpfl_vport->itf.data = dev->data;\n+\tTAILQ_INIT(&cpfl_vport->itf.flow_list);\n \tadapter->vports[param->idx] = cpfl_vport;\n \tadapter->cur_vports |= RTE_BIT32(param->devarg_id);\n \tadapter->cur_vport_nb++;\n@@ -2262,6 +2312,9 @@ cpfl_find_adapter_ext(struct rte_pci_device *pci_dev)\n static void\n cpfl_adapter_ext_deinit(struct cpfl_adapter_ext *adapter)\n {\n+#ifdef RTE_HAS_JANSSON\n+\tcpfl_flow_uninit(adapter);\n+#endif\n \trte_eal_alarm_cancel(cpfl_dev_alarm_handler, adapter);\n \tcpfl_vport_map_uninit(adapter);\n \tidpf_adapter_deinit(&adapter->base);\ndiff --git a/drivers/net/cpfl/cpfl_ethdev.h b/drivers/net/cpfl/cpfl_ethdev.h\nindex 383dbd14c6..69bf32cfbd 100644\n--- a/drivers/net/cpfl/cpfl_ethdev.h\n+++ b/drivers/net/cpfl/cpfl_ethdev.h\n@@ -140,9 +140,12 @@ enum cpfl_itf_type {\n \tCPFL_ITF_TYPE_REPRESENTOR,\n };\n \n+TAILQ_HEAD(cpfl_flow_list, rte_flow);\n+\n struct cpfl_itf {\n \tenum cpfl_itf_type type;\n \tstruct cpfl_adapter_ext *adapter;\n+\tstruct cpfl_flow_list flow_list;\n \tvoid *data;\n };\n \n@@ -206,6 +209,8 @@ struct cpfl_adapter_ext {\n \trte_spinlock_t repr_lock;\n \tstruct rte_hash *repr_allowlist_hash;\n \n+\tstruct cpfl_flow_js_parser *flow_parser;\n+\n \tstruct cpfl_metadata meta;\n };\n \ndiff --git a/drivers/net/cpfl/cpfl_flow.c b/drivers/net/cpfl/cpfl_flow.c\nnew file mode 100644\nindex 0000000000..03dd1ffa44\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_flow.c\n@@ -0,0 +1,339 @@\n+/* SPDX-Lidpfnse-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+#include <rte_flow_driver.h>\n+#include <rte_tailq.h>\n+\n+#include \"cpfl_flow.h\"\n+#include \"cpfl_flow_parser.h\"\n+\n+TAILQ_HEAD(cpfl_flow_engine_list, cpfl_flow_engine);\n+\n+static struct cpfl_flow_engine_list engine_list = TAILQ_HEAD_INITIALIZER(engine_list);\n+\n+void\n+cpfl_flow_engine_register(struct cpfl_flow_engine *engine)\n+{\n+\tTAILQ_INSERT_TAIL(&engine_list, engine, node);\n+}\n+\n+struct cpfl_flow_engine *\n+cpfl_flow_engine_match(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t void **meta)\n+{\n+\tstruct cpfl_flow_engine *engine = NULL;\n+\tvoid *temp;\n+\n+\tRTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {\n+\t\tif (!engine->parse_pattern_action)\n+\t\t\tcontinue;\n+\n+\t\tif (engine->parse_pattern_action(dev, attr, pattern, actions, meta) < 0)\n+\t\t\tcontinue;\n+\t\treturn engine;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+int\n+cpfl_flow_engine_init(struct cpfl_adapter_ext *adapter)\n+{\n+\tstruct cpfl_flow_engine *engine = NULL;\n+\tvoid *temp;\n+\tint ret;\n+\n+\tRTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {\n+\t\tif (!engine->init) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Invalid engine type (%d)\",\n+\t\t\t\t engine->type);\n+\t\t\treturn -ENOTSUP;\n+\t\t}\n+\n+\t\tret = engine->init(adapter);\n+\t\tif (ret) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Failed to initialize engine %d\",\n+\t\t\t\t engine->type);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+cpfl_flow_engine_uninit(struct cpfl_adapter_ext *adapter)\n+{\n+\tstruct cpfl_flow_engine *engine = NULL;\n+\tvoid *temp;\n+\n+\tRTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {\n+\t\tif (engine->uninit)\n+\t\t\tengine->uninit(adapter);\n+\t}\n+}\n+\n+static int\n+cpfl_flow_attr_valid(const struct rte_flow_attr *attr,\n+\t\t struct rte_flow_error *error)\n+{\n+\tif (attr->priority > CPFL_PREC_MAX) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,\n+\t\t\t\t attr, \"Only support priority 0-7.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_flow_param_valid(const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_error *error)\n+{\n+\tint ret;\n+\n+\tif (!pattern) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,\n+\t\t\t\t NULL, \"NULL pattern.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tif (!attr) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR,\n+\t\t\t\t NULL, \"NULL attribute.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tret = cpfl_flow_attr_valid(attr, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ACTION_NUM,\n+\t\t\t\t NULL, \"NULL action.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+__cpfl_flow_validate(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t void **meta,\n+\t\t struct cpfl_flow_engine **engine,\n+\t\t struct rte_flow_error *error)\n+{\n+\tint ret;\n+\n+\tret = cpfl_flow_param_valid(attr, pattern, actions, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t*engine = cpfl_flow_engine_match(dev, attr, pattern, actions, meta);\n+\tif (!*engine) {\n+\t\trte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t NULL, \"No matched engine.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+cpfl_flow_validate(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_error *error)\n+{\n+\tstruct cpfl_flow_engine *engine = NULL;\n+\tint ret;\n+\n+\tret = __cpfl_flow_validate(dev, attr, pattern, actions, NULL, &engine, error);\n+\n+\treturn ret;\n+}\n+\n+struct rte_flow *\n+cpfl_flow_create(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_error *error)\n+{\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tstruct cpfl_flow_engine *engine = NULL;\n+\tstruct rte_flow *flow;\n+\tvoid *meta;\n+\tint ret;\n+\n+\tflow = rte_malloc(NULL, sizeof(struct rte_flow), 0);\n+\tif (!flow) {\n+\t\trte_flow_error_set(error, ENOMEM,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"Failed to allocate memory\");\n+\t\treturn NULL;\n+\t}\n+\n+\tret = __cpfl_flow_validate(dev, attr, pattern, actions, &meta, &engine, error);\n+\tif (ret) {\n+\t\trte_free(flow);\n+\t\treturn NULL;\n+\t}\n+\n+\tif (!engine->create) {\n+\t\trte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t NULL, \"No matched flow creation function\");\n+\t\trte_free(flow);\n+\t\treturn NULL;\n+\t}\n+\n+\tret = engine->create(dev, flow, meta, error);\n+\tif (ret) {\n+\t\trte_free(flow);\n+\t\treturn NULL;\n+\t}\n+\n+\tflow->engine = engine;\n+\tTAILQ_INSERT_TAIL(&itf->flow_list, flow, next);\n+\n+\treturn flow;\n+}\n+\n+int\n+cpfl_flow_destroy(struct rte_eth_dev *dev,\n+\t\t struct rte_flow *flow,\n+\t\t struct rte_flow_error *error)\n+{\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tint ret = 0;\n+\n+\tif (!flow || !flow->engine || !flow->engine->destroy) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t\t NULL, \"Invalid flow\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tret = flow->engine->destroy(dev, flow, error);\n+\tif (!ret)\n+\t\tTAILQ_REMOVE(&itf->flow_list, flow, next);\n+\telse\n+\t\tPMD_DRV_LOG(ERR, \"Failed to destroy flow\");\n+\n+\treturn ret;\n+}\n+\n+int\n+cpfl_flow_flush(struct rte_eth_dev *dev,\n+\t\tstruct rte_flow_error *error)\n+{\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tstruct rte_flow *p_flow;\n+\tvoid *temp;\n+\tint ret = 0;\n+\n+\tRTE_TAILQ_FOREACH_SAFE(p_flow, &itf->flow_list, next, temp) {\n+\t\tret = cpfl_flow_destroy(dev, p_flow, error);\n+\t\tif (ret) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to flush flows\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int\n+cpfl_flow_query(struct rte_eth_dev *dev,\n+\t\tstruct rte_flow *flow,\n+\t\tconst struct rte_flow_action *actions,\n+\t\tvoid *data,\n+\t\tstruct rte_flow_error *error)\n+{\n+\tstruct rte_flow_query_count *count = data;\n+\tint ret = -EINVAL;\n+\n+\tif (!flow || !flow->engine || !flow->engine->query_count) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t\t NULL, \"Invalid flow\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {\n+\t\tswitch (actions->type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n+\t\t\tret = flow->engine->query_count(dev, flow, count, error);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tret = rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t actions,\n+\t\t\t\t\t\t \"action not supported\");\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+const struct rte_flow_ops cpfl_flow_ops = {\n+\t.validate = cpfl_flow_validate,\n+\t.create = cpfl_flow_create,\n+\t.destroy = cpfl_flow_destroy,\n+\t.flush = cpfl_flow_flush,\n+\t.query = cpfl_flow_query,\n+};\n+\n+int\n+cpfl_flow_init(struct cpfl_adapter_ext *ad)\n+{\n+\tint ret;\n+\n+\tif (ad->devargs.flow_parser[0] == '\\0') {\n+\t\tPMD_INIT_LOG(WARNING, \"flow module is not initialized\");\n+\t\treturn 0;\n+\t}\n+\n+\tret = cpfl_flow_engine_init(ad);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to init flow engines\");\n+\t\tgoto err;\n+\t}\n+\n+\tret = cpfl_parser_create(&ad->flow_parser, ad->devargs.flow_parser);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create flow parser\");\n+\t\tgoto err;\n+\t}\n+\n+\treturn ret;\n+\n+err:\n+\tcpfl_flow_engine_uninit(ad);\n+\treturn ret;\n+}\n+\n+void\n+cpfl_flow_uninit(struct cpfl_adapter_ext *ad)\n+{\n+\tif (ad->devargs.flow_parser[0] == '\\0')\n+\t\treturn;\n+\n+\tcpfl_parser_destroy(ad->flow_parser);\n+\tcpfl_flow_engine_uninit(ad);\n+}\ndiff --git a/drivers/net/cpfl/cpfl_flow.h b/drivers/net/cpfl/cpfl_flow.h\nnew file mode 100644\nindex 0000000000..8c19b853ca\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_flow.h\n@@ -0,0 +1,85 @@\n+/* SPDX-Lidpfnse-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+\n+#ifndef _CPFL_FLOW_H_\n+#define _CPFL_FLOW_H_\n+\n+#include <rte_flow.h>\n+#include \"cpfl_ethdev.h\"\n+\n+#define CPFL_PREC_MAX 7\n+\n+extern const struct rte_flow_ops cpfl_flow_ops;\n+\n+enum cpfl_flow_engine_type {\n+\tCPFL_FLOW_ENGINE_NONE = 0,\n+\tCPFL_FLOW_ENGINE_FXP,\n+};\n+\n+typedef int (*engine_init_t)(struct cpfl_adapter_ext *ad);\n+typedef void (*engine_uninit_t)(struct cpfl_adapter_ext *ad);\n+typedef int (*engine_create_t)(struct rte_eth_dev *dev,\n+\t\t\t struct rte_flow *flow,\n+\t\t\t void *meta,\n+\t\t\t struct rte_flow_error *error);\n+typedef int (*engine_destroy_t)(struct rte_eth_dev *dev,\n+\t\t\t\tstruct rte_flow *flow,\n+\t\t\t\tstruct rte_flow_error *error);\n+typedef int (*engine_query_t)(struct rte_eth_dev *dev,\n+\t\t\t struct rte_flow *flow,\n+\t\t\t struct rte_flow_query_count *count,\n+\t\t\t struct rte_flow_error *error);\n+typedef void (*engine_free_t) (struct rte_flow *flow);\n+typedef int (*engine_parse_pattern_action_t)(struct rte_eth_dev *dev,\n+\t\t\t\t\t const struct rte_flow_attr *attr,\n+\t\t\t\t\t const struct rte_flow_item pattern[],\n+\t\t\t\t\t const struct rte_flow_action actions[],\n+\t\t\t\t\t void **meta);\n+\n+struct cpfl_flow_engine {\n+\tTAILQ_ENTRY(cpfl_flow_engine) node;\n+\tenum cpfl_flow_engine_type type;\n+\tengine_init_t init;\n+\tengine_uninit_t uninit;\n+\tengine_create_t create;\n+\tengine_destroy_t destroy;\n+\tengine_query_t query_count;\n+\tengine_free_t free;\n+\tengine_parse_pattern_action_t parse_pattern_action;\n+};\n+\n+struct rte_flow {\n+\tTAILQ_ENTRY(rte_flow) next;\n+\tstruct cpfl_flow_engine *engine;\n+\tvoid *rule;\n+};\n+\n+void cpfl_flow_engine_register(struct cpfl_flow_engine *engine);\n+struct cpfl_flow_engine *cpfl_flow_engine_match(struct rte_eth_dev *dev,\n+\t\t\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\t\t\tconst struct rte_flow_item pattern[],\n+\t\t\t\t\t\tconst struct rte_flow_action actions[],\n+\t\t\t\t\t\tvoid **meta);\n+int cpfl_flow_engine_init(struct cpfl_adapter_ext *adapter);\n+void cpfl_flow_engine_uninit(struct cpfl_adapter_ext *adapter);\n+int cpfl_flow_init(struct cpfl_adapter_ext *ad);\n+void cpfl_flow_uninit(struct cpfl_adapter_ext *ad);\n+struct rte_flow *cpfl_flow_create(struct rte_eth_dev *dev,\n+\t\t\t\t const struct rte_flow_attr *attr,\n+\t\t\t\t const struct rte_flow_item pattern[],\n+\t\t\t\t const struct rte_flow_action actions[],\n+\t\t\t\t struct rte_flow_error *error);\n+int cpfl_flow_validate(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t const struct rte_flow_item pattern[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_error *error);\n+int cpfl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error);\n+int cpfl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error);\n+int cpfl_flow_query(struct rte_eth_dev *dev,\n+\t\t struct rte_flow *flow,\n+\t\t const struct rte_flow_action *actions,\n+\t\t void *data,\n+\t\t struct rte_flow_error *error);\n+#endif\ndiff --git a/drivers/net/cpfl/meson.build b/drivers/net/cpfl/meson.build\nindex d767818eb7..f5654d5b0e 100644\n--- a/drivers/net/cpfl/meson.build\n+++ b/drivers/net/cpfl/meson.build\n@@ -41,6 +41,7 @@ endif\n \n if dpdk_conf.has('RTE_HAS_JANSSON')\n sources += files(\n+\t 'cpfl_flow.c',\n 'cpfl_flow_parser.c',\n )\n ext_deps += jansson_dep\n", "prefixes": [ "v10", "3/9" ] }{ "id": 132404, "url": "