get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130255,
    "url": "http://patchwork.dpdk.org/api/patches/130255/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230812075506.361769-6-yuying.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20230812075506.361769-6-yuying.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230812075506.361769-6-yuying.zhang@intel.com",
    "date": "2023-08-12T07:55:06",
    "name": "[v1,5/5] net/cpfl: add fxp flow engine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f574ff6714e1cacbda00a7080cc64cd7f056e346",
    "submitter": {
        "id": 1844,
        "url": "http://patchwork.dpdk.org/api/people/1844/?format=api",
        "name": "Zhang, Yuying",
        "email": "yuying.zhang@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patchwork.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230812075506.361769-6-yuying.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 29205,
            "url": "http://patchwork.dpdk.org/api/series/29205/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=29205",
            "date": "2023-08-12T07:55:01",
            "name": "add rte flow support for cpfl",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/29205/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/130255/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/130255/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 3C0C84303E;\n\tSat, 12 Aug 2023 09:32:51 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id E0DC843268;\n\tSat, 12 Aug 2023 09:32:32 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [192.55.52.93])\n by mails.dpdk.org (Postfix) with ESMTP id C316143271\n for <dev@dpdk.org>; Sat, 12 Aug 2023 09:32:30 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 12 Aug 2023 00:32:30 -0700",
            "from dpdk-yuyingzh-icelake.sh.intel.com ([10.67.116.226])\n by fmsmga008.fm.intel.com with ESMTP; 12 Aug 2023 00:32:28 -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=1691825551; x=1723361551;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=Vanq2r40Yx3ZA0+7jgIy4QaelsnHSDtyrJ6nqfnTEwY=;\n b=YbWNukDRe92ufm27Qb4yDOHaDIv/UxESjoziZQGFi4SodFsXHCJDwto6\n dgJRIcnUBDeYjtuH3Szqm71YRv9r6TUEws9FiPFj7U0oy492ix08GTKfZ\n Ugr6ezdwonc6sgy56NRWj2Ma2s8UGTMBFDk5ZD8AqHbDSYQJKOCE/6Va+\n p81PatTnoBm0DTvIrNJWH7dtW1QVadSEn6/PzSwR81Y29HZswangVhcP1\n 19uqCXdyctJTObP0y49nwvxuovx5P94l88d/iiBPJJqIU+A1OFYXGfMEI\n 0buogaUUbL0pqqya9Pqs/v/vw/7YpK3lzQAduBlef9OSAfY/HGWyXd0DJ Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10799\"; a=\"369282010\"",
            "E=Sophos;i=\"6.01,167,1684825200\"; d=\"scan'208\";a=\"369282010\"",
            "E=McAfee;i=\"6600,9927,10799\"; a=\"798268365\"",
            "E=Sophos;i=\"6.01,167,1684825200\"; d=\"scan'208\";a=\"798268365\""
        ],
        "X-ExtLoop1": "1",
        "From": "Yuying Zhang <yuying.zhang@intel.com>",
        "To": "dev@dpdk.org, beilei.xing@intel.com, qi.z.zhang@intel.com,\n jingjing.wu@intel.com",
        "Cc": "Yuying Zhang <yuying.zhang@intel.com>",
        "Subject": "[PATCH v1 5/5] net/cpfl: add fxp flow engine",
        "Date": "Sat, 12 Aug 2023 07:55:06 +0000",
        "Message-Id": "<20230812075506.361769-6-yuying.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230812075506.361769-1-yuying.zhang@intel.com>",
        "References": "<20230812075506.361769-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": "Adapt fxp low level as a flow engine.\n\nSigned-off-by: Yuying Zhang <yuying.zhang@intel.com>\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n drivers/net/cpfl/cpfl_ethdev.h          |  85 ++++\n drivers/net/cpfl/cpfl_flow_engine_fxp.c | 610 ++++++++++++++++++++++++\n drivers/net/cpfl/meson.build            |   1 +\n 3 files changed, 696 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 63bcc5551f..d7e9ea1a74 100644\n--- a/drivers/net/cpfl/cpfl_ethdev.h\n+++ b/drivers/net/cpfl/cpfl_ethdev.h\n@@ -92,6 +92,8 @@\n \n #define CPFL_RX_CFGQ_NUM\t4\n #define CPFL_TX_CFGQ_NUM\t4\n+#define CPFL_FPCP_CFGQ_TX       0\n+#define CPFL_FPCP_CFGQ_RX       1\n #define CPFL_CFGQ_NUM\t\t8\n \n struct cpfl_vport_param {\n@@ -230,6 +232,8 @@ struct cpfl_adapter_ext {\n \tstruct rte_hash *repr_whitelist_hash;\n \n \tstruct cpfl_flow_js_parser *flow_parser;\n+\tstruct rte_bitmap *mod_bm;\n+\tvoid *mod_bm_mem;\n \n \t/* ctrl vport and ctrl queues. */\n \tstruct cpfl_vport ctrl_vport;\n@@ -265,5 +269,86 @@ int cpfl_packets_dispatch(void *arg);\n \t((struct cpfl_repr *)((dev)->data->dev_private))\n #define CPFL_DEV_TO_ITF(dev)\t\t\t\t\\\n \t((struct cpfl_itf *)((dev)->data->dev_private))\n+#define CPFL_INVALID_HW_ID      UINT16_MAX\n+\n+static inline uint16_t\n+cpfl_get_port_id(struct cpfl_itf *itf)\n+{\n+\tif (!itf)\n+\t\treturn CPFL_INVALID_HW_ID;\n+\n+\tif (itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\tstruct cpfl_vport *vport = (void *)itf;\n+\n+\t\treturn vport->base.devarg_id;\n+\t}\n+\n+\treturn CPFL_INVALID_HW_ID;\n+}\n+\n+static inline uint16_t\n+cpfl_get_vsi_id(struct cpfl_itf *itf)\n+{\n+\tstruct cpfl_adapter_ext *adapter = itf->adapter;\n+\tstruct cpfl_vport_info *info;\n+\tuint32_t vport_id;\n+\tint ret;\n+\tstruct cpfl_vport_id vport_identity;\n+\n+\tif (!itf)\n+\t\treturn CPFL_INVALID_HW_ID;\n+\n+\tif (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {\n+\t\tstruct cpfl_repr *repr = (void *)itf;\n+\n+\t\treturn repr->vport_info->vport_info.vsi_id;\n+\t} else if (itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\tvport_id = ((struct cpfl_vport *)itf)->base.vport_id;\n+\t\tvport_identity.func_type = CPCHNL2_FUNC_TYPE_PF;\n+\t\t/* host: HOST0_CPF_ID, acc: ACC_CPF_ID */\n+\t\tvport_identity.pf_id = ACC_CPF_ID;\n+\t\tvport_identity.vf_id = 0;\n+\t\tvport_identity.vport_id = vport_id;\n+\n+\t\tret = rte_hash_lookup_data(adapter->vport_map_hash, &vport_identity,\n+\t\t\t\t\t  (void **)&info);\n+\t\tif (ret < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"vport id not exist\");\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\t/* rte_spinlock_unlock(&adapter->vport_map_lock); */\n+\t\treturn info->vport_info.vsi_id;\n+\t}\n+\n+err:\n+\t/* rte_spinlock_unlock(&adapter->vport_map_lock); */\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+\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 \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..e10639c842\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\n@@ -0,0 +1,610 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 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 <ethdev_driver.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 \"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+#include \"rte_memcpy.h\"\n+\n+#define COOKIE_DEF\t0x1000\n+#define PREC_MAX\t7\n+#define PREC_DEF\t1\n+#define PREC_SET\t5\n+#define TYPE_ID\t\t3\n+#define OFFSET\t\t0x0a\n+#define HOST_ID_DEF\t0\n+#define PF_NUM_DEF\t0\n+#define PORT_NUM_DEF\t0\n+#define RESP_REQ_DEF\t2\n+#define PIN_TO_CACHE_DEF\t0\n+#define CLEAR_MIRROR_1ST_STATE_DEF  0\n+#define FIXED_FETCH_DEF 0\n+#define PTI_DEF\t\t0\n+#define MOD_OBJ_SIZE_DEF\t0\n+#define PIN_MOD_CONTENT_DEF\t0\n+\n+#define MAX_MOD_CONTENT_INDEX\t256\n+#define MAX_MR_ACTION_NUM 8\n+\n+struct rule_info_meta {\n+\tstruct cpfl_flow_pr_action pr_action;\n+\tuint32_t pr_num;\n+\tuint32_t mr_num;\n+\tuint32_t rule_num;\n+\tstruct cpfl_rule_info rules[0];\n+};\n+\n+static uint32_t fxp_mod_idx_alloc(struct cpfl_adapter_ext *ad);\n+static void fxp_mod_idx_free(struct cpfl_adapter_ext *ad, uint32_t idx);\n+uint64_t rule_cookie = 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 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\tcpq_id = vport->base.devarg_id * 2;\n+\t} else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {\n+\t\tcpq_id = CPFL_FPCP_CFGQ_TX;\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_update(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1],\n+\t\t\t       rim->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 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\tcpfl_fxp_rule_free(flow);\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 if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {\n+\t\tcpq_id = CPFL_FPCP_CFGQ_TX;\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_update(itf, ad->ctlqp[cpq_id], ad->ctlqp[cpq_id + 1], rim->rules,\n+\t\t\t       rim->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\tfxp_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 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 = PIN_TO_CACHE_DEF;\n+\t\trinfo->sem.fixed_fetch = 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(PREC_DEF,\n+\t\t\t\t\tmr_action->mod.prof,\n+\t\t\t\t\tPTI_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 = fxp_mod_idx_alloc(adapter);\n+\tif (mod_idx == 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(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 = MOD_OBJ_SIZE_DEF;\n+\tminfo->pin_mod_content = PIN_MOD_CONTENT_DEF;\n+\tminfo->mod_index = mod_idx;\n+\tmod_rinfo->cookie = 0x1237561;\n+\tmod_rinfo->port_num = PORT_NUM_DEF;\n+\tmod_rinfo->resp_req = 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+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 rule_info_meta *rim,\n+\t\t      int priority,\n+\t\t      int index,\n+\t\t      bool is_vport_rule)\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 REPRESENTED_PORT or REPRESENTED_PORT type */\n+\tstruct cpfl_itf *dst_itf;\n+\tuint16_t dev_id; /*vsi_id or phyical port id*/\n+\tbool is_vsi;\n+\tbool set_meta_valid = false;\n+\tint queue_id = -1;\n+\tbool fwd_vsi = false;\n+\tbool fwd_q = false;\n+\tbool fwd_jump = 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 = PREC_MAX - priority;\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_REPRESENTED_PORT:\n+\t\tcase RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:\n+\t\t\tif (!fwd_vsi && !fwd_jump)\n+\t\t\t\tfwd_vsi = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\t\t\tif (is_vport_rule) {\n+\t\t\t\tdst_itf = itf;\n+\t\t\t} else {\n+\t\t\t\tact_ethdev = action->conf;\n+\t\t\t\tdst_itf = cpfl_get_itf_by_port_id(act_ethdev->port_id);\n+\t\t\t}\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 = -2;\n+\t\t\t}\n+\n+\t\t\tis_vsi = (action_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR ||\n+\t\t\t\tdst_itf->type == CPFL_ITF_TYPE_REPRESENTOR);\n+\t\t\tif (is_vsi || is_vport_rule)\n+\t\t\t\tdev_id = cpfl_get_vsi_id(dst_itf);\n+\t\t\telse\n+\t\t\t\tdev_id = cpfl_get_port_id(dst_itf);\n+\n+\t\t\tif (dev_id == CPFL_INVALID_HW_ID)\n+\t\t\t\tgoto err;\n+\n+\t\t\tif (is_vsi || is_vport_rule)\n+\t\t\t\t*act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);\n+\t\t\telse\n+\t\t\t\t*act_set = cpfl_act_fwd_port(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 && !fwd_jump)\n+\t\t\t\tfwd_q = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\t\t\tif (queue_id == -2)\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+#define FXP_MAX_QREGION_SIZE 128\n+\t\t\tif (!(rte_is_power_of_2(rss->queue_num) &&\n+\t\t\t      rss->queue_num <= FXP_MAX_QREGION_SIZE))\n+\t\t\t\tgoto err;\n+\n+\t\t\tif (!fwd_q && !fwd_jump)\n+\t\t\t\tfwd_q = true;\n+\t\t\telse\n+\t\t\t\tgoto err;\n+\t\t\tif (queue_id == -2)\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 != NULL && !set_meta_valid) {\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 (rule_cookie == ~0llu)\n+\t\trule_cookie = COOKIE_DEF;\n+\trinfo->cookie = rule_cookie++;\n+\trinfo->host_id = HOST_ID_DEF;\n+\trinfo->port_num = PORT_NUM_DEF;\n+\trinfo->resp_req = RESP_REQ_DEF;\n+\trinfo->clear_mirror_1st_state = CLEAR_MIRROR_1ST_STATE_DEF;\n+}\n+\n+static bool is_mod_action(const struct rte_flow_action actions[], bool *set_meta_valid)\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\tcase RTE_FLOW_ACTION_TYPE_MODIFY_FIELD:\n+\t\t\treturn true;\n+\t\tcase RTE_FLOW_ACTION_TYPE_SET_TAG:\n+\t\t\t*set_meta_valid = true;\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[MAX_MR_ACTION_NUM] = { 0 };\n+\tuint32_t pr_num = 0, mr_num = 0;\n+\tstruct cpfl_vport *vport;\n+\tstruct rule_info_meta *rim;\n+\tbool set_meta_valid = false;\n+\tint ret;\n+\n+\tif (itf->type == CPFL_ITF_TYPE_VPORT) {\n+\t\tvport = (struct cpfl_vport *)itf;\n+\t\tif (vport->exceptional) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Can't create rte_flow with exceptional vport.\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\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 (is_mod_action(actions, &set_meta_valid)) {\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\tif (!set_meta_valid)\n+\t\t\tmr_num++;\n+\t}\n+\n+\tpr_num = 1;\n+\trim = rte_zmalloc(NULL,\n+\t\t\t  sizeof(struct 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 input set\");\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,\n+\t\t\t\t  0, false)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid input set\");\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 fxp_mod_init(struct cpfl_adapter_ext *ad)\n+{\n+\tuint32_t size = rte_bitmap_get_memory_footprint(MAX_MOD_CONTENT_INDEX);\n+\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(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 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 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 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 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+\tfxp_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 = 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 4061123034..ce46d7e76e 100644\n--- a/drivers/net/cpfl/meson.build\n+++ b/drivers/net/cpfl/meson.build\n@@ -43,6 +43,7 @@ js_dep = dependency('json-c', required: false, method : 'pkg-config')\n if js_dep.found()\n     sources += files(\n         'cpfl_flow.c',\n+\t'cpfl_flow_engine_fxp.c',\n         'cpfl_flow_parser.c',\n         'cpfl_rules.c',\n         'cpfl_controlq.c',\n",
    "prefixes": [
        "v1",
        "5/5"
    ]
}