get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/131802/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 131802,
    "url": "http://patches.dpdk.org/api/patches/131802/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230822010226.17783-8-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": "<20230822010226.17783-8-yuying.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230822010226.17783-8-yuying.zhang@intel.com",
    "date": "2023-08-22T01:02:25",
    "name": "[v6,7/8] net/cpfl: add fxp flow engine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "dcce9cffe0a8ee216e3d19aa46198dee8dfa936d",
    "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/20230822010226.17783-8-yuying.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 29591,
            "url": "http://patches.dpdk.org/api/series/29591/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29591",
            "date": "2023-08-22T01:02:18",
            "name": "add rte flow support for cpfl",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/29591/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/131802/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/131802/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 20BB742608;\n\tThu, 21 Sep 2023 18:59:50 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 885F740ED9;\n\tThu, 21 Sep 2023 18:59:18 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [192.55.52.120])\n by mails.dpdk.org (Postfix) with ESMTP id DCCD240E64\n for <dev@dpdk.org>; Thu, 21 Sep 2023 18:59:13 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 21 Sep 2023 09:59:10 -0700",
            "from dpdk-pengyuan-mev.sh.intel.com ([10.67.119.128])\n by fmsmga004.fm.intel.com with ESMTP; 21 Sep 2023 09:59:07 -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=1695315554; x=1726851554;\n h=from:to:subject:date:message-id:in-reply-to:references:\n mime-version:content-transfer-encoding;\n bh=O/8QRJxP5UMH2tGwaWfnIRsK2A99b8RMadY7XGp2nyo=;\n b=UPxgNEOWaUUFIe3Z8I69YuxNasg2Ta1iyCZ1gkMMnFiC9fn4RT9TEc2L\n WSnftXwDuB4JaBzAn+71ubJ+elXXSxwafuS6dijcIVsyQf+UbDD11vPGa\n 5IOCqMKBUyM6CBd6lukSD8SxMpbz4ut4+YByxdl0TPAtcugWe2RIQ0U62\n zmbbpYnNtJLf+tz4BzkZAKTsROCPiSXKicvS6mOgu2HKKZ+wnqXAItPmG\n wRnyRq0tjWtTAECU4rUzlMGFfRTyhkFlE2x4Qbl20FH7Yx+AAKTRmCw1K\n 3g61L8fFuuqPwWePzJWQsUqEDGzqoDc8XXdjMvHrw9iuW/bRmXdsKWVd1 A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10840\"; a=\"379468328\"",
            "E=Sophos;i=\"6.03,165,1694761200\"; d=\"scan'208\";a=\"379468328\"",
            "E=McAfee;i=\"6600,9927,10840\"; a=\"817472307\"",
            "E=Sophos;i=\"6.03,165,1694761200\"; d=\"scan'208\";a=\"817472307\""
        ],
        "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 v6 7/8] net/cpfl: add fxp flow engine",
        "Date": "Tue, 22 Aug 2023 01:02:25 +0000",
        "Message-Id": "<20230822010226.17783-8-yuying.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230822010226.17783-1-yuying.zhang@intel.com>",
        "References": "<20230915100047.90153-1-yuying.zhang@intel.com>\n <20230822010226.17783-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 low level as a flow engine.\n\nSigned-off-by: Yuying Zhang <yuying.zhang@intel.com>\n---\n drivers/net/cpfl/cpfl_ethdev.h          |  27 ++\n drivers/net/cpfl/cpfl_flow_engine_fxp.c | 583 ++++++++++++++++++++++++\n drivers/net/cpfl/meson.build            |   1 +\n 3 files changed, 611 insertions(+)\n create mode 100644 drivers/net/cpfl/cpfl_flow_engine_fxp.c",
    "diff": "diff --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..e0c08a77c3\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\n@@ -0,0 +1,583 @@\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_memcpy.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\trte_memcpy(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(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": [
        "v6",
        "7/8"
    ]
}