Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/132408/?format=api
https://patches.dpdk.org/api/patches/132408/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230908160552.148060-8-yuying.zhang@intel.com/", "project": { "id": 1, "url": "https://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-8-yuying.zhang@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20230908160552.148060-8-yuying.zhang@intel.com", "date": "2023-09-08T16:05:50", "name": "[v10,7/9] net/cpfl: adapt FXP to flow engine", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "e33a597bcdad716d9a9cc4aa51a9bd55d9132bfe", "submitter": { "id": 1844, "url": "https://patches.dpdk.org/api/people/1844/?format=api", "name": "Zhang, Yuying", "email": "yuying.zhang@intel.com" }, "delegate": { "id": 1540, "url": "https://patches.dpdk.org/api/users/1540/?format=api", "username": "qzhan15", "first_name": "Qi", "last_name": "Zhang", "email": "qi.z.zhang@intel.com" }, "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230908160552.148060-8-yuying.zhang@intel.com/mbox/", "series": [ { "id": 29766, "url": "https://patches.dpdk.org/api/series/29766/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29766", "date": "2023-09-08T16:05:43", "name": "add rte flow support for cpfl", "version": 10, "mbox": "https://patches.dpdk.org/series/29766/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/132408/comments/", "check": "warning", "checks": "https://patches.dpdk.org/api/patches/132408/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 8C35142338;\n\tMon, 9 Oct 2023 10:03:25 +0200 (CEST)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id CB2DF40A71;\n\tMon, 9 Oct 2023 10:02:33 +0200 (CEST)", "from mgamail.intel.com (mgamail.intel.com [134.134.136.126])\n by mails.dpdk.org (Postfix) with ESMTP id 8C5ED406B7\n for <dev@dpdk.org>; Mon, 9 Oct 2023 10:02:31 +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:31 -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:29 -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=1696838551; x=1728374551;\n h=from:to:subject:date:message-id:in-reply-to:references:\n mime-version:content-transfer-encoding;\n bh=l7jOq7OvLTIPTf0r4Wsj0o7v2NBLXKkpzZJWbCk2v3E=;\n b=kjAhFmsdcbZrOz8X3563eGLlx81eYqRCXVR7is1JYTn5TRkjtrgA8mxV\n x2wDdGnuGqAy6eVqkxJoOkh0YCi+JDOsSqmDfdA/np1Ggs/tE6j06ibPT\n LNrSEN8W0gdBAFX7g91ie4nmKUP6i5yeDgrYS3VD2qlTjOqu0eV1dfECN\n VLUlF210nGCMgU2ydvM8lvnzDAQldBRAa8PuJNGHUkXPbDALTdUzSRvaw\n dXa4bdc0QAgTTR8UCWRoYYdH6Lx6L8ViCwQbtH//tnFzGxqVkfOO8NhRP\n svD3aPdBNdaeROCKkOn86saP9G7j9PlLgjtmkcPMbzRyJZdjjoHhzVXCS g==;", "X-IronPort-AV": [ "E=McAfee;i=\"6600,9927,10857\"; a=\"369155081\"", "E=Sophos;i=\"6.03,209,1694761200\"; d=\"scan'208\";a=\"369155081\"", "E=McAfee;i=\"6600,9927,10857\"; a=\"926675915\"", "E=Sophos;i=\"6.03,209,1694761200\"; d=\"scan'208\";a=\"926675915\"" ], "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 7/9] net/cpfl: adapt FXP to flow engine", "Date": "Fri, 8 Sep 2023 16:05:50 +0000", "Message-Id": "<20230908160552.148060-8-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\nAdapt FXP implementation to a flow engine\n\nSigned-off-by: Yuying Zhang <yuying.zhang@intel.com>\nAcked-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n doc/guides/nics/cpfl.rst | 18 +-\n doc/guides/rel_notes/release_23_11.rst | 1 +\n drivers/net/cpfl/cpfl_ethdev.h | 27 ++\n drivers/net/cpfl/cpfl_flow_engine_fxp.c | 582 ++++++++++++++++++++++++\n drivers/net/cpfl/meson.build | 1 +\n 5 files changed, 627 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/cpfl/cpfl_flow_engine_fxp.c", "diff": "diff --git a/doc/guides/nics/cpfl.rst b/doc/guides/nics/cpfl.rst\nindex e17347d15c..ae5487f2f6 100644\n--- a/doc/guides/nics/cpfl.rst\n+++ b/doc/guides/nics/cpfl.rst\n@@ -197,8 +197,22 @@ low level hardware resources.\n \n * For Ubuntu, it can be installed using `apt install libjansson-dev`\n \n-- run testpmd with the json file\n+- run testpmd with the json file, create two vports\n \n .. code-block:: console\n \n- dpdk-testpmd -c 0x3 -n 4 -a 0000:af:00.6,vport=[0],flow_parser=\"refpkg.json\" -- -i\n+ dpdk-testpmd -c 0x3 -n 4 -a 0000:af:00.6,vport=[0-1],flow_parser=\"refpkg.json\" -- -i\n+\n+#. Create one flow to forward ETH-IPV4-TCP from I/O port to a local(CPF's) vport. Flow should be created on\n+ vport X. Group M should match fxp module. Action port_representor Y means forward packet to local vport Y::\n+\n+ .. code-block:: console\n+\n+ flow create X ingress group M pattern eth dst is 00:01:00:00:03:14 / ipv4 src is 192.168.0.1 \\\n+ dst is 192.168.0.2 / tcp / end actions port_representor port_id Y / end\n+\n+#. Send a matched packet, and it should be displayed on PMD::\n+\n+ .. code-block:: console\n+\n+ sendp(Ether(dst='00:01:00:00:03:14')/IP(src='192.168.0.1',dst='192.168.0.2')/TCP(),iface=\"ens25f0\")\ndiff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst\nindex 8536ce88f4..16cdd674d3 100644\n--- a/doc/guides/rel_notes/release_23_11.rst\n+++ b/doc/guides/rel_notes/release_23_11.rst\n@@ -85,6 +85,7 @@ New Features\n * **Updated Intel cpfl driver.**\n \n * Added support for port representor.\n+ * Added support for rte_flow.\n \n * **Updated Intel iavf driver.**\n * Added support for iavf auto-reset.\ndiff --git a/drivers/net/cpfl/cpfl_ethdev.h b/drivers/net/cpfl/cpfl_ethdev.h\nindex 8eeeac9910..efb0eb5251 100644\n--- a/drivers/net/cpfl/cpfl_ethdev.h\n+++ b/drivers/net/cpfl/cpfl_ethdev.h\n@@ -85,6 +85,8 @@\n \n #define CPFL_RX_CFGQ_NUM\t4\n #define CPFL_TX_CFGQ_NUM\t4\n+#define CPFL_FPCP_CFGQ_TX\t0\n+#define CPFL_FPCP_CFGQ_RX\t1\n #define CPFL_CFGQ_NUM\t\t8\n \n /* bit[15:14] type\n@@ -219,6 +221,8 @@ struct cpfl_adapter_ext {\n \tstruct rte_hash *repr_allowlist_hash;\n \n \tstruct cpfl_flow_js_parser *flow_parser;\n+\tstruct rte_bitmap *mod_bm;\n+\tvoid *mod_bm_mem;\n \n \tstruct cpfl_metadata meta;\n \n@@ -312,4 +316,27 @@ cpfl_get_vsi_id(struct cpfl_itf *itf)\n \treturn CPFL_INVALID_HW_ID;\n }\n \n+static inline struct cpfl_itf *\n+cpfl_get_itf_by_port_id(uint16_t port_id)\n+{\n+\tstruct rte_eth_dev *dev;\n+\n+\tif (port_id >= RTE_MAX_ETHPORTS) {\n+\t\tPMD_DRV_LOG(ERR, \"port_id should be < %d.\", RTE_MAX_ETHPORTS);\n+\t\treturn NULL;\n+\t}\n+\n+\tdev = &rte_eth_devices[port_id];\n+\tif (dev->state == RTE_ETH_DEV_UNUSED) {\n+\t\tPMD_DRV_LOG(ERR, \"eth_dev[%d] is unused.\", port_id);\n+\t\treturn NULL;\n+\t}\n+\n+\tif (!dev->data) {\n+\t\tPMD_DRV_LOG(ERR, \"eth_dev[%d] data not be allocated.\", port_id);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn CPFL_DEV_TO_ITF(dev);\n+}\n #endif /* _CPFL_ETHDEV_H_ */\ndiff --git a/drivers/net/cpfl/cpfl_flow_engine_fxp.c b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\nnew file mode 100644\nindex 0000000000..4c7b4deb7a\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\n@@ -0,0 +1,582 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Intel Corporation\n+ */\n+\n+#include <sys/queue.h>\n+#include <stdio.h>\n+#include <errno.h>\n+#include <stdint.h>\n+#include <string.h>\n+#include <unistd.h>\n+#include <stdarg.h>\n+#include <math.h>\n+#include <rte_debug.h>\n+#include <rte_ether.h>\n+#include <rte_log.h>\n+#include <rte_malloc.h>\n+#include <rte_eth_ctrl.h>\n+#include <rte_tailq.h>\n+#include <rte_flow_driver.h>\n+#include <rte_flow.h>\n+#include <rte_bitmap.h>\n+#include <ethdev_driver.h>\n+#include \"cpfl_rules.h\"\n+#include \"cpfl_logs.h\"\n+#include \"cpfl_ethdev.h\"\n+#include \"cpfl_flow.h\"\n+#include \"cpfl_fxp_rule.h\"\n+#include \"cpfl_flow_parser.h\"\n+\n+#define CPFL_COOKIE_DEF\t\t0x1000\n+#define CPFL_MOD_COOKIE_DEF\t0x1237561\n+#define CPFL_PREC_DEF\t\t1\n+#define CPFL_PREC_SET\t\t5\n+#define CPFL_TYPE_ID\t\t3\n+#define CPFL_OFFSET\t\t0x0a\n+#define CPFL_HOST_ID_DEF\t0\n+#define CPFL_PF_NUM_DEF\t\t0\n+#define CPFL_PORT_NUM_DEF\t0\n+#define CPFL_RESP_REQ_DEF\t2\n+#define CPFL_PIN_TO_CACHE_DEF\t0\n+#define CPFL_CLEAR_MIRROR_1ST_STATE_DEF\t0\n+#define CPFL_FIXED_FETCH_DEF\t0\n+#define CPFL_PTI_DEF\t\t0\n+#define CPFL_MOD_OBJ_SIZE_DEF\t0\n+#define CPFL_PIN_MOD_CONTENT_DEF\t0\n+\n+#define CPFL_MAX_MOD_CONTENT_INDEX\t256\n+#define CPFL_MAX_MR_ACTION_NUM\t8\n+\n+/* Struct used when parse detailed rule information with json file */\n+struct cpfl_rule_info_meta {\n+\tstruct cpfl_flow_pr_action pr_action;\t/* json action field of pattern rule */\n+\tuint32_t pr_num;\t\t\t/* number of pattern rules */\n+\tuint32_t mr_num;\t\t\t/* number of modification rules */\n+\tuint32_t rule_num;\t\t\t/* number of all rules */\n+\tstruct cpfl_rule_info rules[0];\n+};\n+\n+static uint32_t cpfl_fxp_mod_idx_alloc(struct cpfl_adapter_ext *ad);\n+static void cpfl_fxp_mod_idx_free(struct cpfl_adapter_ext *ad, uint32_t idx);\n+uint64_t cpfl_rule_cookie = CPFL_COOKIE_DEF;\n+\n+static int\n+cpfl_fxp_create(struct rte_eth_dev *dev,\n+\t\tstruct rte_flow *flow,\n+\t\tvoid *meta,\n+\t\tstruct rte_flow_error *error)\n+{\n+\tint ret = 0;\n+\tuint32_t cpq_id = 0;\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tstruct cpfl_adapter_ext *ad = itf->adapter;\n+\tstruct cpfl_rule_info_meta *rim = meta;\n+\tstruct cpfl_vport *vport;\n+\n+\tif (!rim)\n+\t\treturn ret;\n+\n+\tif (itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\tvport = (struct cpfl_vport *)itf;\n+\t\t/* Every vport has one pair control queues configured to handle message.\n+\t\t * Even index is tx queue and odd index is rx queue.\n+\t\t */\n+\t\tcpq_id = vport->base.devarg_id * 2;\n+\t} else {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"fail to find correct control queue\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tret = cpfl_rule_process(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1],\n+\t\t\t\trim->rules, rim->rule_num, true);\n+\tif (ret < 0) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"cpfl filter create flow fail\");\n+\t\trte_free(rim);\n+\t\treturn ret;\n+\t}\n+\n+\tflow->rule = rim;\n+\n+\treturn ret;\n+}\n+\n+static inline void\n+cpfl_fxp_rule_free(struct rte_flow *flow)\n+{\n+\trte_free(flow->rule);\n+\tflow->rule = NULL;\n+}\n+\n+static int\n+cpfl_fxp_destroy(struct rte_eth_dev *dev,\n+\t\t struct rte_flow *flow,\n+\t\t struct rte_flow_error *error)\n+{\n+\tint ret = 0;\n+\tuint32_t cpq_id = 0;\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tstruct cpfl_adapter_ext *ad = itf->adapter;\n+\tstruct cpfl_rule_info_meta *rim;\n+\tuint32_t i;\n+\tstruct cpfl_vport *vport;\n+\n+\trim = flow->rule;\n+\tif (!rim) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"no such flow create by cpfl filter\");\n+\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tif (itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\tvport = (struct cpfl_vport *)itf;\n+\t\tcpq_id = vport->base.devarg_id * 2;\n+\t} else {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"fail to find correct control queue\");\n+\t\tret = -rte_errno;\n+\t\tgoto err;\n+\t}\n+\n+\tret = cpfl_rule_process(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1], rim->rules,\n+\t\t\t\trim->rule_num, false);\n+\tif (ret < 0) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t\t \"fail to destroy cpfl filter rule\");\n+\t\tgoto err;\n+\t}\n+\n+\t/* free mod index */\n+\tfor (i = rim->pr_num; i < rim->rule_num; i++)\n+\t\tcpfl_fxp_mod_idx_free(ad, rim->rules[i].mod.mod_index);\n+err:\n+\tcpfl_fxp_rule_free(flow);\n+\treturn ret;\n+}\n+\n+static bool\n+cpfl_fxp_parse_pattern(const struct cpfl_flow_pr_action *pr_action,\n+\t\t struct cpfl_rule_info_meta *rim,\n+\t\t int i)\n+{\n+\tif (pr_action->type == CPFL_JS_PR_ACTION_TYPE_SEM) {\n+\t\tstruct cpfl_rule_info *rinfo = &rim->rules[i];\n+\n+\t\trinfo->type = CPFL_RULE_TYPE_SEM;\n+\t\trinfo->sem.prof_id = pr_action->sem.prof;\n+\t\trinfo->sem.sub_prof_id = pr_action->sem.subprof;\n+\t\trinfo->sem.key_byte_len = pr_action->sem.keysize;\n+\t\tmemcpy(rinfo->sem.key, pr_action->sem.cpfl_flow_pr_fv, rinfo->sem.key_byte_len);\n+\t\trinfo->sem.pin_to_cache = CPFL_PIN_TO_CACHE_DEF;\n+\t\trinfo->sem.fixed_fetch = CPFL_FIXED_FETCH_DEF;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid pattern item.\");\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static int\n+cpfl_parse_mod_content(struct cpfl_adapter_ext *adapter,\n+\t\t struct cpfl_rule_info *match_rinfo,\n+\t\t struct cpfl_rule_info *mod_rinfo,\n+\t\t const struct cpfl_flow_mr_action *mr_action)\n+{\n+\tstruct cpfl_mod_rule_info *minfo = &mod_rinfo->mod;\n+\tuint32_t mod_idx;\n+\tint i;\n+\tint next = match_rinfo->act_byte_len / (sizeof(union cpfl_action_set));\n+\tunion cpfl_action_set *act_set =\n+\t\t&((union cpfl_action_set *)match_rinfo->act_bytes)[next];\n+\n+\tif (!mr_action || mr_action->type != CPFL_JS_MR_ACTION_TYPE_MOD)\n+\t\treturn -EINVAL;\n+\n+\t*act_set = cpfl_act_mod_profile(CPFL_PREC_DEF,\n+\t\t\t\t\tmr_action->mod.prof,\n+\t\t\t\t\tCPFL_PTI_DEF,\n+\t\t\t\t\t0, /* append */\n+\t\t\t\t\t0, /* prepend */\n+\t\t\t\t\tCPFL_ACT_MOD_PROFILE_PREFETCH_256B);\n+\n+\tact_set++;\n+\tmatch_rinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\n+\tmod_idx = cpfl_fxp_mod_idx_alloc(adapter);\n+\tif (mod_idx == CPFL_MAX_MOD_CONTENT_INDEX) {\n+\t\tPMD_DRV_LOG(ERR, \"Out of Mod Index.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t*act_set = cpfl_act_mod_addr(CPFL_PREC_DEF, mod_idx);\n+\n+\tact_set++;\n+\tmatch_rinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\n+\tmod_rinfo->type = CPFL_RULE_TYPE_MOD;\n+\tminfo->mod_obj_size = CPFL_MOD_OBJ_SIZE_DEF;\n+\tminfo->pin_mod_content = CPFL_PIN_MOD_CONTENT_DEF;\n+\tminfo->mod_index = mod_idx;\n+\tmod_rinfo->cookie = CPFL_MOD_COOKIE_DEF;\n+\tmod_rinfo->port_num = CPFL_PORT_NUM_DEF;\n+\tmod_rinfo->resp_req = CPFL_RESP_REQ_DEF;\n+\n+\tminfo->mod_content_byte_len = mr_action->mod.byte_len + 2;\n+\tfor (i = 0; i < minfo->mod_content_byte_len; i++)\n+\t\tminfo->mod_content[i] = mr_action->mod.data[i];\n+\n+\treturn 0;\n+}\n+\n+#define CPFL_FXP_MAX_QREGION_SIZE 128\n+#define CPFL_INVALID_QUEUE_ID -2\n+static int\n+cpfl_fxp_parse_action(struct cpfl_itf *itf,\n+\t\t const struct rte_flow_action *actions,\n+\t\t const struct cpfl_flow_mr_action *mr_action,\n+\t\t struct cpfl_rule_info_meta *rim,\n+\t\t int priority,\n+\t\t int index)\n+{\n+\tconst struct rte_flow_action_ethdev *act_ethdev;\n+\tconst struct rte_flow_action *action;\n+\tconst struct rte_flow_action_queue *act_q;\n+\tconst struct rte_flow_action_rss *rss;\n+\tstruct rte_eth_dev_data *data;\n+\tenum rte_flow_action_type action_type;\n+\tstruct cpfl_vport *vport;\n+\t/* used when action is PORT_REPRESENTOR type */\n+\tstruct cpfl_itf *dst_itf;\n+\tuint16_t dev_id; /* vsi id */\n+\tint queue_id = -1;\n+\tbool fwd_vsi = false;\n+\tbool fwd_q = false;\n+\tuint32_t i;\n+\tstruct cpfl_rule_info *rinfo = &rim->rules[index];\n+\tunion cpfl_action_set *act_set = (void *)rinfo->act_bytes;\n+\n+\tpriority = CPFL_PREC_MAX - priority;\n+\tfor (action = actions; action->type !=\n+\t RTE_FLOW_ACTION_TYPE_END; action++) {\n+\t\taction_type = action->type;\n+\t\tswitch (action_type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:\n+\t\t\tif (!fwd_vsi)\n+\t\t\t\tfwd_vsi = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\n+\t\t\tact_ethdev = action->conf;\n+\t\t\tdst_itf = cpfl_get_itf_by_port_id(act_ethdev->port_id);\n+\n+\t\t\tif (!dst_itf)\n+\t\t\t\tgoto err;\n+\n+\t\t\tif (dst_itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\t\t\tvport = (struct cpfl_vport *)dst_itf;\n+\t\t\t\tqueue_id = vport->base.chunks_info.rx_start_qid;\n+\t\t\t} else {\n+\t\t\t\tqueue_id = CPFL_INVALID_QUEUE_ID;\n+\t\t\t}\n+\n+\t\t\tdev_id = cpfl_get_vsi_id(dst_itf);\n+\n+\t\t\tif (dev_id == CPFL_INVALID_HW_ID)\n+\t\t\t\tgoto err;\n+\n+\t\t\t*act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);\n+\t\t\tact_set++;\n+\t\t\trinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n+\t\t\tif (!fwd_q)\n+\t\t\t\tfwd_q = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\t\t\tif (queue_id == CPFL_INVALID_QUEUE_ID)\n+\t\t\t\tgoto err;\n+\t\t\tact_q = action->conf;\n+\t\t\tdata = itf->data;\n+\t\t\tif (act_q->index >= data->nb_rx_queues)\n+\t\t\t\tgoto err;\n+\n+\t\t\tvport = (struct cpfl_vport *)itf;\n+\t\t\tif (queue_id < 0)\n+\t\t\t\tqueue_id = vport->base.chunks_info.rx_start_qid;\n+\t\t\tqueue_id += act_q->index;\n+\t\t\t*act_set = cpfl_act_set_hash_queue(priority, 0, queue_id, 0);\n+\t\t\tact_set++;\n+\t\t\trinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_RSS:\n+\t\t\trss = action->conf;\n+\t\t\tif (rss->queue_num <= 1)\n+\t\t\t\tgoto err;\n+\t\t\tfor (i = 0; i < rss->queue_num - 1; i++) {\n+\t\t\t\tif (rss->queue[i + 1] != rss->queue[i] + 1)\n+\t\t\t\t\tgoto err;\n+\t\t\t}\n+\t\t\tdata = itf->data;\n+\t\t\tif (rss->queue[rss->queue_num - 1] >= data->nb_rx_queues)\n+\t\t\t\tgoto err;\n+\t\t\tif (!(rte_is_power_of_2(rss->queue_num) &&\n+\t\t\t rss->queue_num <= CPFL_FXP_MAX_QREGION_SIZE))\n+\t\t\t\tgoto err;\n+\n+\t\t\tif (!fwd_q)\n+\t\t\t\tfwd_q = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\t\t\tif (queue_id == CPFL_INVALID_QUEUE_ID)\n+\t\t\t\tgoto err;\n+\t\t\tvport = (struct cpfl_vport *)itf;\n+\t\t\tif (queue_id < 0)\n+\t\t\t\tqueue_id = vport->base.chunks_info.rx_start_qid;\n+\t\t\tqueue_id += rss->queue[0];\n+\t\t\t*act_set = cpfl_act_set_hash_queue_region(priority, 0, queue_id,\n+\t\t\t\t\t\t\t\t log(rss->queue_num) / log(2), 0);\n+\t\t\tact_set++;\n+\t\t\trinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n+\t\t\t(*act_set).data = cpfl_act_drop(priority).data;\n+\t\t\tact_set++;\n+\t\t\trinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\t\t\t(*act_set).data = cpfl_act_set_commit_mode(priority, 0).data;\n+\t\t\tact_set++;\n+\t\t\trinfo->act_byte_len += sizeof(union cpfl_action_set);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto err;\n+\t\t}\n+\t}\n+\n+\tif (mr_action) {\n+\t\tuint32_t i;\n+\n+\t\tfor (i = 0; i < rim->mr_num; i++)\n+\t\t\tif (cpfl_parse_mod_content(itf->adapter, rinfo,\n+\t\t\t\t\t\t &rim->rules[rim->pr_num + i],\n+\t\t\t\t\t\t &mr_action[i]))\n+\t\t\t\tgoto err;\n+\t}\n+\n+\treturn 0;\n+\n+err:\n+\tPMD_DRV_LOG(ERR, \"Invalid action type\");\n+\treturn -EINVAL;\n+}\n+\n+static void\n+cpfl_fill_rinfo_default_value(struct cpfl_rule_info *rinfo)\n+{\n+\tif (cpfl_rule_cookie == ~0llu)\n+\t\tcpfl_rule_cookie = CPFL_COOKIE_DEF;\n+\trinfo->cookie = cpfl_rule_cookie++;\n+\trinfo->host_id = CPFL_HOST_ID_DEF;\n+\trinfo->port_num = CPFL_PORT_NUM_DEF;\n+\trinfo->resp_req = CPFL_RESP_REQ_DEF;\n+\trinfo->clear_mirror_1st_state = CPFL_CLEAR_MIRROR_1ST_STATE_DEF;\n+}\n+\n+static bool\n+cpfl_is_mod_action(const struct rte_flow_action actions[])\n+{\n+\tconst struct rte_flow_action *action;\n+\tenum rte_flow_action_type action_type;\n+\n+\tif (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END)\n+\t\treturn false;\n+\n+\tfor (action = actions; action->type !=\n+\t\t\tRTE_FLOW_ACTION_TYPE_END; action++) {\n+\t\taction_type = action->type;\n+\t\tswitch (action_type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\treturn true;\n+\t\tdefault:\n+\t\t\tcontinue;\n+\t\t}\n+\t}\n+\treturn false;\n+}\n+\n+static int\n+cpfl_fxp_parse_pattern_action(struct rte_eth_dev *dev,\n+\t\t\t const struct rte_flow_attr *attr,\n+\t\t\t const struct rte_flow_item pattern[],\n+\t\t\t const struct rte_flow_action actions[],\n+\t\t\t void **meta)\n+{\n+\tstruct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);\n+\tstruct cpfl_flow_pr_action pr_action = { 0 };\n+\tstruct cpfl_adapter_ext *adapter = itf->adapter;\n+\tstruct cpfl_flow_mr_action mr_action[CPFL_MAX_MR_ACTION_NUM] = { 0 };\n+\tuint32_t pr_num = 0;\n+\tuint32_t mr_num = 0;\n+\tstruct cpfl_rule_info_meta *rim;\n+\tint ret;\n+\n+\tret = cpfl_flow_parse_items(itf, adapter->flow_parser, pattern, attr, &pr_action);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"No Match pattern support.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (cpfl_is_mod_action(actions)) {\n+\t\tret = cpfl_flow_parse_actions(adapter->flow_parser, actions, mr_action);\n+\t\tif (ret) {\n+\t\t\tPMD_DRV_LOG(ERR, \"action parse fails.\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tmr_num++;\n+\t}\n+\n+\tpr_num = 1;\n+\trim = rte_zmalloc(NULL,\n+\t\t\t sizeof(struct cpfl_rule_info_meta) +\n+\t\t\t (pr_num + mr_num) * sizeof(struct cpfl_rule_info),\n+\t\t\t 0);\n+\tif (!rim)\n+\t\treturn -ENOMEM;\n+\n+\trim->pr_action = pr_action;\n+\trim->pr_num = pr_num;\n+\trim->mr_num = mr_num;\n+\trim->rule_num = pr_num + mr_num;\n+\n+\tif (!cpfl_fxp_parse_pattern(&pr_action, rim, 0)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid pattern\");\n+\t\trte_free(rim);\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tif (cpfl_fxp_parse_action(itf, actions, mr_action, rim, attr->priority, 0)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid action\");\n+\t\trte_free(rim);\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tcpfl_fill_rinfo_default_value(&rim->rules[0]);\n+\n+\tif (!meta)\n+\t\trte_free(rim);\n+\telse\n+\t\t*meta = rim;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_fxp_mod_init(struct cpfl_adapter_ext *ad)\n+{\n+\tuint32_t size = rte_bitmap_get_memory_footprint(CPFL_MAX_MOD_CONTENT_INDEX);\n+\tvoid *mem = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);\n+\n+\tif (!mem)\n+\t\treturn -ENOMEM;\n+\n+\t/* a set bit represent a free slot */\n+\tad->mod_bm = rte_bitmap_init_with_all_set(CPFL_MAX_MOD_CONTENT_INDEX, mem, size);\n+\tif (!ad->mod_bm) {\n+\t\trte_free(mem);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tad->mod_bm_mem = mem;\n+\n+\treturn 0;\n+}\n+\n+static void\n+cpfl_fxp_mod_uninit(struct cpfl_adapter_ext *ad)\n+{\n+\trte_free(ad->mod_bm_mem);\n+\tad->mod_bm_mem = NULL;\n+\tad->mod_bm = NULL;\n+}\n+\n+static uint32_t\n+cpfl_fxp_mod_idx_alloc(struct cpfl_adapter_ext *ad)\n+{\n+\tuint64_t slab = 0;\n+\tuint32_t pos = 0;\n+\n+\tif (!rte_bitmap_scan(ad->mod_bm, &pos, &slab))\n+\t\treturn CPFL_MAX_MOD_CONTENT_INDEX;\n+\n+\tpos += __builtin_ffsll(slab) - 1;\n+\trte_bitmap_clear(ad->mod_bm, pos);\n+\n+\treturn pos;\n+}\n+\n+static void\n+cpfl_fxp_mod_idx_free(struct cpfl_adapter_ext *ad, uint32_t idx)\n+{\n+\trte_bitmap_set(ad->mod_bm, idx);\n+}\n+\n+static int\n+cpfl_fxp_query(struct rte_eth_dev *dev __rte_unused,\n+\t struct rte_flow *flow __rte_unused,\n+\t struct rte_flow_query_count *count __rte_unused,\n+\t struct rte_flow_error *error)\n+{\n+\trte_flow_error_set(error, EINVAL,\n+\t\t\t RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t NULL,\n+\t\t\t \"count action not supported by this module\");\n+\n+\treturn -rte_errno;\n+}\n+\n+static void\n+cpfl_fxp_uninit(struct cpfl_adapter_ext *ad)\n+{\n+\tcpfl_fxp_mod_uninit(ad);\n+}\n+\n+static int\n+cpfl_fxp_init(struct cpfl_adapter_ext *ad)\n+{\n+\tint ret = 0;\n+\n+\tret = cpfl_fxp_mod_init(ad);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to init mod content bitmap.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static struct\n+cpfl_flow_engine cpfl_fxp_engine = {\n+\t.type = CPFL_FLOW_ENGINE_FXP,\n+\t.init = cpfl_fxp_init,\n+\t.uninit = cpfl_fxp_uninit,\n+\t.create = cpfl_fxp_create,\n+\t.destroy = cpfl_fxp_destroy,\n+\t.query_count = cpfl_fxp_query,\n+\t.parse_pattern_action = cpfl_fxp_parse_pattern_action,\n+};\n+\n+RTE_INIT(cpfl_sw_engine_init)\n+{\n+\tstruct cpfl_flow_engine *engine = &cpfl_fxp_engine;\n+\n+\tcpfl_flow_engine_register(engine);\n+}\ndiff --git a/drivers/net/cpfl/meson.build b/drivers/net/cpfl/meson.build\nindex 6118a16329..5fd1cbd045 100644\n--- a/drivers/net/cpfl/meson.build\n+++ b/drivers/net/cpfl/meson.build\n@@ -46,6 +46,7 @@ if dpdk_conf.has('RTE_HAS_JANSSON')\n \t 'cpfl_flow.c',\n 'cpfl_flow_parser.c',\n \t 'cpfl_fxp_rule.c',\n+\t 'cpfl_flow_engine_fxp.c',\n )\n ext_deps += jansson_dep\n endif\n", "prefixes": [ "v10", "7/9" ] }{ "id": 132408, "url": "