get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 135496,
    "url": "http://patches.dpdk.org/api/patches/135496/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231222100837.260493-2-wenjing.qiao@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": "<20231222100837.260493-2-wenjing.qiao@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231222100837.260493-2-wenjing.qiao@intel.com",
    "date": "2023-12-22T10:08:39",
    "name": "[1/2] net/cpfl: parse flow offloading hint from P4 context file",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "32b379f5fa845ea1614bda8cba6eb22c98652467",
    "submitter": {
        "id": 2680,
        "url": "http://patches.dpdk.org/api/people/2680/?format=api",
        "name": "Wenjing Qiao",
        "email": "wenjing.qiao@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/20231222100837.260493-2-wenjing.qiao@intel.com/mbox/",
    "series": [
        {
            "id": 30653,
            "url": "http://patches.dpdk.org/api/series/30653/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=30653",
            "date": "2023-12-22T10:08:36",
            "name": "net/cpfl: support flow offloading for P4",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/30653/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/135496/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/135496/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 8A3BA4375D;\n\tFri, 22 Dec 2023 11:10:04 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7819D402F0;\n\tFri, 22 Dec 2023 11:10:04 +0100 (CET)",
            "from mgamail.intel.com (mgamail.intel.com [134.134.136.20])\n by mails.dpdk.org (Postfix) with ESMTP id 799F74067C\n for <dev@dpdk.org>; Fri, 22 Dec 2023 11:10:02 +0100 (CET)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 Dec 2023 02:10:01 -0800",
            "from dpdk-wenjing-02.sh.intel.com ([10.67.118.228])\n by fmsmga001.fm.intel.com with ESMTP; 22 Dec 2023 02:09:58 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1703239802; x=1734775802;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=Ow9tbu4BYmF06S7u8KRkX6H5qIvINhV0u3Vr51gsOY0=;\n b=BNgWdb/1yjrOMzGNCRXJRQNDxAnRsNCiNGEQS43iNSCi8MTmKGlCc9+r\n hZ2cmnyfQiEGtsIndgqlEzzmatF/XGLMhspRvx5tLP7JxFb3h5Ot22j3s\n ZmmjGkJSf9rZbh+f8U7WKh8v31wnW4dfZHScpEaDcLmr5cm+lw8fbN5VZ\n GhKIJEPB1JkOPPWMDSu6J/crd+neeiWKofdf1Eiv3uNNgPwKLt1fElnbk\n h/F+lPFeobmJSUqY+Ej6nMHZPkxokSPMnwt4qPJCwFBplkK1UKBpcc93t\n QlbIvu8noYuOftxvPYEdgHndyStvnoyAzImAZI0XYqkLl7PBQB2b/Tx6l w==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10931\"; a=\"386525288\"",
            "E=Sophos;i=\"6.04,296,1695711600\"; d=\"scan'208\";a=\"386525288\"",
            "E=McAfee;i=\"6600,9927,10931\"; a=\"920605319\"",
            "E=Sophos;i=\"6.04,296,1695711600\"; d=\"scan'208\";a=\"920605319\""
        ],
        "X-ExtLoop1": "1",
        "From": "wenjing.qiao@intel.com",
        "To": "jingjing.wu@intel.com,\n\tbeilei.xing@intel.com,\n\tqi.z.zhang@intel.com",
        "Cc": "dev@dpdk.org,\n\tWenjing Qiao <wenjing.qiao@intel.com>",
        "Subject": "[PATCH 1/2] net/cpfl: parse flow offloading hint from P4 context file",
        "Date": "Fri, 22 Dec 2023 10:08:39 +0000",
        "Message-Id": "<20231222100837.260493-2-wenjing.qiao@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20231222100837.260493-1-wenjing.qiao@intel.com>",
        "References": "<20231222100837.260493-1-wenjing.qiao@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: Wenjing Qiao <wenjing.qiao@intel.com>\n\nTo supporting P4-programmed network controller, reuse devargs\n\"flow_parser\" to specify the path of a p4 context JSON configure\nfile. The cpfl PMD use the JSON configuration file to translate\nrte_flow tokens into low level hardware representation.\n\nNote, the p4 context JSON file is generated by the P4 compiler\nand is intended to work exclusively with a specific P4 pipeline\nconfiguration, which must be compiled and programmed into the hardware.\n\nSigned-off-by: Wenjing Qiao <wenjing.qiao@intel.com>\n---\n drivers/net/cpfl/cpfl_ethdev.h          |    9 +-\n drivers/net/cpfl/cpfl_flow.c            |   10 +-\n drivers/net/cpfl/cpfl_flow_engine_fxp.c |    9 +-\n drivers/net/cpfl/cpfl_flow_parser.c     |   60 +-\n drivers/net/cpfl/cpfl_flow_parser.h     |    2 +-\n drivers/net/cpfl/cpfl_tdi_parser.c      | 1715 +++++++++++++++++++++++\n drivers/net/cpfl/cpfl_tdi_parser.h      |  293 ++++\n drivers/net/cpfl/meson.build            |    1 +\n 8 files changed, 2077 insertions(+), 22 deletions(-)\n create mode 100644 drivers/net/cpfl/cpfl_tdi_parser.c\n create mode 100644 drivers/net/cpfl/cpfl_tdi_parser.h",
    "diff": "diff --git a/drivers/net/cpfl/cpfl_ethdev.h b/drivers/net/cpfl/cpfl_ethdev.h\nindex 457db6d6be..e580f80f2f 100644\n--- a/drivers/net/cpfl/cpfl_ethdev.h\n+++ b/drivers/net/cpfl/cpfl_ethdev.h\n@@ -185,6 +185,12 @@ struct cpfl_repr {\n \tbool func_up; /* If the represented function is up */\n };\n \n+struct cpfl_flow_parser {\n+\tstruct cpfl_flow_js_parser *fixed_parser;\n+\tstruct cpfl_tdi_program *p4_parser;\n+\tbool is_p4_parser;\n+};\n+\n struct cpfl_metadata_chunk {\n \tint type;\n \tuint8_t data[CPFL_META_CHUNK_LENGTH];\n@@ -218,8 +224,7 @@ struct cpfl_adapter_ext {\n \n \trte_spinlock_t repr_lock;\n \tstruct rte_hash *repr_allowlist_hash;\n-\n-\tstruct cpfl_flow_js_parser *flow_parser;\n+\tstruct cpfl_flow_parser flow_parser;\n \tstruct rte_bitmap *mod_bm;\n \tvoid *mod_bm_mem;\n \ndiff --git a/drivers/net/cpfl/cpfl_flow.c b/drivers/net/cpfl/cpfl_flow.c\nindex 3ba6c0f0e7..1c4131da2c 100644\n--- a/drivers/net/cpfl/cpfl_flow.c\n+++ b/drivers/net/cpfl/cpfl_flow.c\n@@ -6,6 +6,7 @@\n \n #include \"cpfl_flow.h\"\n #include \"cpfl_flow_parser.h\"\n+#include \"cpfl_tdi_parser.h\"\n \n TAILQ_HEAD(cpfl_flow_engine_list, cpfl_flow_engine);\n \n@@ -331,9 +332,14 @@ cpfl_flow_init(struct cpfl_adapter_ext *ad, struct cpfl_devargs *devargs)\n void\n cpfl_flow_uninit(struct cpfl_adapter_ext *ad)\n {\n-\tif (ad->flow_parser == NULL)\n+\tif (ad->flow_parser.fixed_parser == NULL && ad->flow_parser.p4_parser == NULL)\n \t\treturn;\n \n-\tcpfl_parser_destroy(ad->flow_parser);\n+\tif (ad->flow_parser.fixed_parser)\n+\t\tcpfl_parser_destroy(ad->flow_parser.fixed_parser);\n+\n+\tif (ad->flow_parser.p4_parser)\n+\t\tcpfl_tdi_program_destroy(ad->flow_parser.p4_parser);\n+\n \tcpfl_flow_engine_uninit(ad);\n }\ndiff --git a/drivers/net/cpfl/cpfl_flow_engine_fxp.c b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\nindex 8a4e1419b4..f269ff97e1 100644\n--- a/drivers/net/cpfl/cpfl_flow_engine_fxp.c\n+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c\n@@ -503,20 +503,25 @@ cpfl_fxp_parse_pattern_action(struct rte_eth_dev *dev,\n \tstruct cpfl_rule_info_meta *rim;\n \tint ret;\n \n+\tif (adapter->flow_parser.is_p4_parser)\n+\t\treturn -EINVAL;\n+\n \tret = cpfl_fxp_get_metadata_port(itf, actions);\n \tif (!ret) {\n \t\tPMD_DRV_LOG(ERR, \"Fail to save metadata.\");\n \t\treturn -EINVAL;\n \t}\n \n-\tret = cpfl_flow_parse_items(itf, adapter->flow_parser, pattern, attr, &pr_action);\n+\tret = cpfl_flow_parse_items(itf, adapter->flow_parser.fixed_parser, pattern, attr,\n+\t\t\t\t    &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\tret = cpfl_flow_parse_actions(adapter->flow_parser.fixed_parser,\n+\t\t\t\t\t      actions, mr_action);\n \t\tif (ret) {\n \t\t\tPMD_DRV_LOG(ERR, \"action parse fails.\");\n \t\t\treturn -EINVAL;\ndiff --git a/drivers/net/cpfl/cpfl_flow_parser.c b/drivers/net/cpfl/cpfl_flow_parser.c\nindex a8f0488f21..e7f8a8a6cc 100644\n--- a/drivers/net/cpfl/cpfl_flow_parser.c\n+++ b/drivers/net/cpfl/cpfl_flow_parser.c\n@@ -5,6 +5,7 @@\n #include <arpa/inet.h>\n \n #include \"cpfl_flow_parser.h\"\n+#include \"cpfl_tdi_parser.h\"\n \n static enum rte_flow_item_type\n cpfl_get_item_type_by_str(const char *type)\n@@ -938,36 +939,65 @@ cpfl_parser_init(json_t *ob_root, struct cpfl_flow_js_parser *parser)\n \treturn 0;\n }\n \n+static int\n+cpfl_check_is_p4_mode(json_t *ob_root)\n+{\n+\treturn json_object_get(ob_root, \"patterns\") ? false : true;\n+}\n+\n int\n-cpfl_parser_create(struct cpfl_flow_js_parser **flow_parser, const char *filename)\n+cpfl_parser_create(struct cpfl_flow_parser *flow_parser, const char *filename)\n {\n \tstruct cpfl_flow_js_parser *parser;\n+\tstruct cpfl_tdi_program *prog;\n \tjson_error_t json_error;\n \tjson_t *root;\n \tint ret;\n \n-\tparser = rte_zmalloc(\"flow_parser\", sizeof(struct cpfl_flow_js_parser), 0);\n-\tif (!parser) {\n-\t\tPMD_DRV_LOG(ERR, \"Not enough memory to create flow parser.\");\n-\t\treturn -ENOMEM;\n-\t}\n \troot = json_load_file(filename, 0, &json_error);\n \tif (!root) {\n \t\tPMD_DRV_LOG(ERR, \"Bad JSON file \\\"%s\\\": %s\", filename, json_error.text);\n-\t\tgoto free_parser;\n+\t\treturn -EINVAL;\n \t}\n-\tret = cpfl_parser_init(root, parser);\n-\tif (ret < 0) {\n-\t\tPMD_DRV_LOG(ERR, \"parser init failed.\");\n-\t\tgoto free_parser;\n+\n+\tif (cpfl_check_is_p4_mode(root)) {\n+\t\tPMD_DRV_LOG(NOTICE, \"flow parser mode is p4 mode.\");\n+\t\tprog = rte_zmalloc(\"tdi_parser\", sizeof(struct cpfl_tdi_program), 0);\n+\t\tif (prog == NULL) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to create program object.\");\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t\tret = cpfl_tdi_program_create(root, prog);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Failed to create tdi program from file %s\", filename);\n+\t\t\trte_free(prog);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tflow_parser->p4_parser = prog;\n+\t\tflow_parser->fixed_parser = NULL;\n+\t\tflow_parser->is_p4_parser = true;\n+\t} else {\n+\t\tPMD_DRV_LOG(NOTICE, \"flow parser mode is fixed function mode.\");\n+\t\tparser = rte_zmalloc(\"flow_parser\", sizeof(struct cpfl_flow_js_parser), 0);\n+\t\tif (!parser) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Not enough memory to create flow parser.\");\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\n+\t\tret = cpfl_parser_init(root, parser);\n+\t\tif (ret < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"parser init failed.\");\n+\t\t\trte_free(parser);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tflow_parser->fixed_parser = parser;\n+\t\tflow_parser->p4_parser = NULL;\n+\t\tflow_parser->is_p4_parser = false;\n \t}\n-\t*flow_parser = parser;\n+\n \tjson_decref(root);\n \n \treturn 0;\n-free_parser:\n-\trte_free(parser);\n-\treturn -EINVAL;\n }\n \n static void\ndiff --git a/drivers/net/cpfl/cpfl_flow_parser.h b/drivers/net/cpfl/cpfl_flow_parser.h\nindex 23904e39f1..d420464d5c 100644\n--- a/drivers/net/cpfl/cpfl_flow_parser.h\n+++ b/drivers/net/cpfl/cpfl_flow_parser.h\n@@ -273,7 +273,7 @@ struct cpfl_flow_mr_action {\n \t};\n };\n \n-int cpfl_parser_create(struct cpfl_flow_js_parser **parser, const char *filename);\n+int cpfl_parser_create(struct cpfl_flow_parser *flow_parser, const char *filename);\n int cpfl_parser_destroy(struct cpfl_flow_js_parser *parser);\n int cpfl_flow_parse_items(struct cpfl_itf *itf,\n \t\t\t  struct cpfl_flow_js_parser *parser,\ndiff --git a/drivers/net/cpfl/cpfl_tdi_parser.c b/drivers/net/cpfl/cpfl_tdi_parser.c\nnew file mode 100644\nindex 0000000000..ed12ef04ad\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_tdi_parser.c\n@@ -0,0 +1,1715 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+#include <errno.h>\n+#include <rte_malloc.h>\n+\n+#include \"cpfl_tdi_parser.h\"\n+\n+static int\n+cpfl_tdi_get_integer_obj(json_t *jobj, const char *key, int *output)\n+{\n+\tjson_t *int_obj = json_object_get(jobj, key);\n+\n+\tif (int_obj == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Missing %s\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_integer(int_obj)) {\n+\t\tPMD_DRV_LOG(ERR, \"%s is not a integer object.\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*output = json_integer_value(int_obj);\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_get_string_obj(json_t *jobj, const char *key, char *output)\n+{\n+\tjson_t *str_obj = json_object_get(jobj, key);\n+\n+\tif (str_obj == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Missing %s\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_string(str_obj)) {\n+\t\tPMD_DRV_LOG(ERR, \"%s is not a string object.\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tstrncpy(output, json_string_value(str_obj), CPFL_TDI_JSON_STR_SIZE_MAX - 1);\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_get_boolean_obj(json_t *jobj, const char *key, bool *output)\n+{\n+\tjson_t *bool_obj = json_object_get(jobj, key);\n+\n+\tif (bool_obj == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Missing %s\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_boolean(bool_obj)) {\n+\t\tPMD_DRV_LOG(ERR, \"%s is not a boolean object.\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*output = (bool)json_integer_value(bool_obj);\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_get_array_obj(json_t *jobj, const char *key, json_t **output)\n+{\n+\tjson_t *array_obj = json_object_get(jobj, key);\n+\n+\tif (array_obj == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Missing %s\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_array(array_obj)) {\n+\t\tPMD_DRV_LOG(ERR, \"%s is not a array object.\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*output = array_obj;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_get_object_obj(json_t *jobj, const char *key, json_t **output)\n+{\n+\tjson_t *obj_obj = json_object_get(jobj, key);\n+\n+\tif (obj_obj == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Missing %s\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_object(obj_obj)) {\n+\t\tPMD_DRV_LOG(ERR, \"%s is not a array object.\", key);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*output = obj_obj;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_table_type(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tchar tt[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"table_type\", tt);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(tt, \"match\")) {\n+\t\ttable->table_type = CPFL_TDI_TABLE_TYPE_MATCH;\n+\t} else if (!strcmp(tt, \"match_value_lookup_table\")) {\n+\t\ttable->table_type = CPFL_TDI_TABLE_TYPE_MATCH_VALUE_LOOKUP_TABLE;\n+\t} else if (!strcmp(tt, \"policer_meter\")) {\n+\t\ttable->table_type = CPFL_TDI_TABLE_TYPE_POLICER_METER;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown table type %s\", tt);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_table_dir(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tchar dir[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"direction\", dir);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(dir, \"RX\")) {\n+\t\ttable->direction = CPFL_TDI_TABLE_DIR_RX;\n+\t} else if (!strcmp(dir, \"TX\")) {\n+\t\ttable->direction = CPFL_TDI_TABLE_DIR_TX;\n+\t} else if (!strcmp(dir, \"BIDIRECTIONAL\")) {\n+\t\ttable->direction = CPFL_TDI_TABLE_DIR_BI;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown direction type %s\", dir);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_type(json_t *root, struct cpfl_tdi_match_key_field *mkf)\n+{\n+\tchar mt[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"match_type\", mt);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tif (!strcmp(mt, \"exact\")) {\n+\t\tmkf->match_type = CPFL_TDI_MATCH_TYPE_EXACT;\n+\t} else if (!strcmp(mt, \"selector\")) {\n+\t\tmkf->match_type = CPFL_TDI_MATCH_TYPE_SELECTOR;\n+\t} else if (!strcmp(mt, \"ternary\")) {\n+\t\tmkf->match_type = CPFL_TDI_MATCH_TYPE_TERNARY;\n+\t} else if (!strcmp(mt, \"lpm\")) {\n+\t\tmkf->match_type = CPFL_TDI_MATCH_TYPE_LPM;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported match type %s.\", mt);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_key_field_obj(json_t *root, struct cpfl_tdi_match_key_field *mkf)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", mkf->name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"instance_name\", mkf->instance_name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"field_name\", mkf->field_name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_match_type(root, mkf);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"bit_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->bit_width = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"index\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->index = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"position\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->position = (uint32_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_key_fields(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\ttable->match_key_field_num = (uint16_t)array_len;\n+\ttable->match_key_fields =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_match_key_field) * array_len, 0);\n+\tif (table->match_key_fields == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create match key field array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *mkf_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_match_key_field_obj(mkf_object, &table->match_key_fields[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_byte_order(json_t *root, struct cpfl_tdi_match_key_format *mkf)\n+{\n+\tchar bo[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"byte_order\", bo);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(bo, \"HOST\")) {\n+\t\tmkf->byte_order = CPFL_TDI_BYTE_ORDER_HOST;\n+\t} else if (!strcmp(bo, \"NETWORK\")) {\n+\t\tmkf->byte_order = CPFL_TDI_BYTE_ORDER_NETWORK;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown byte order type %s\", bo);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_key_format_obj(json_t *root, struct cpfl_tdi_match_key_format *mkf)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"match_key_handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->match_key_handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_parse_byte_order(root, mkf);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"byte_array_index\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->byte_array_index = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"start_bit_offset\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->start_bit_offset = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"bit_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmkf->bit_width = (uint16_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_key_format_array(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\ttable->match_key_format_num = (uint16_t)array_len;\n+\ttable->match_key_format =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_match_key_format) * array_len, 0);\n+\tif (table->match_key_format == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create match key format array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *mkf_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_match_key_format_obj(mkf_object, &table->match_key_format[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_p4_parameter_obj(json_t *root, struct cpfl_tdi_p4_parameter *param)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", param->name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"bit_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tparam->bit_width = (uint16_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_p4_parameters(json_t *root, struct cpfl_tdi_action *act)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tact->p4_parameter_num = (uint16_t)array_len;\n+\tact->p4_parameters = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_p4_parameter) * array_len, 0);\n+\tif (act->p4_parameters == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create p4 parameter array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *pp_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_p4_parameter_obj(pp_object, &act->p4_parameters[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_action_obj(json_t *root, struct cpfl_tdi_action *act)\n+{\n+\tint ret, val = 0;\n+\tjson_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", act->name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tact->handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_boolean_obj(root, \"constant_default_action\",\n+\t\t\t\t       &act->constant_default_action);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_boolean_obj(root, \"is_compiler_added_action\",\n+\t\t\t\t       &act->is_compiler_added_action);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_boolean_obj(root, \"allowed_as_hit_action\", &act->allowed_as_hit_action);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_boolean_obj(root, \"allowed_as_default_action\",\n+\t\t\t\t       &act->allowed_as_default_action);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"p4_parameters\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn cpfl_tdi_parse_p4_parameters(jobj, act);\n+}\n+\n+static int\n+cpfl_tdi_parse_actions(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\ttable->action_num = (uint16_t)array_len;\n+\ttable->actions = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_action) * array_len, 0);\n+\tif (table->actions == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create action array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *act_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_action_obj(act_object, &table->actions[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_ma_hw_block(json_t *root, struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", name);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(name, \"SEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_SEM;\n+\t} else if (!strcmp(name, \"LEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_LEM;\n+\t} else if (!strcmp(name, \"WCM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_WCM;\n+\t} else if (!strcmp(name, \"LPM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_LPM;\n+\t} else if (!strcmp(name, \"MOD\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_MOD;\n+\t} else if (!strcmp(name, \"HASH\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_HASH;\n+\t} else if (!strcmp(name, \"RC\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_RC;\n+\t} else if (!strcmp(name, \"CXP_LEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_CXP_LEM;\n+\t} else if (!strcmp(name, \"METER\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_METER;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown hardware block type %s\", name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_profiles(json_t *root, struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len > 16) {\n+\t\tPMD_DRV_LOG(ERR, \"Profile array out of bound: %d.\", array_len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\thb->profile_num = (uint16_t)array_len;\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tint val;\n+\t\tjson_t *int_obj = json_array_get(root, i);\n+\n+\t\tif (!json_is_integer(int_obj)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Invalid profile id, not an integer.\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tval = json_integer_value(int_obj);\n+\t\thb->profile[i] = (uint8_t)val;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_immediate_field_obj(json_t *root, struct cpfl_tdi_immediate_field *imf)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"param_name\", imf->param_name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"param_handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\timf->param_handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"dest_start\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\timf->dest_start = (uint16_t)val;\n+\tif (json_object_get(root, \"start_bit_offset\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"start_bit_offset\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\timf->start_bit_offset = (uint16_t)val;\n+\t}\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"dest_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\timf->dest_width = (uint16_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_af_immediate_fields(json_t *root, struct cpfl_tdi_action_format *af)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\taf->immediate_field_num = (uint16_t)array_len;\n+\taf->immediate_fields =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_immediate_field) * array_len, 0);\n+\tif (af->immediate_fields == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to immediate field array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *if_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_immediate_field_obj(if_object, &af->immediate_fields[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_field_type(json_t *root, struct cpfl_tdi_mod_field *mf)\n+{\n+\tchar t[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\tint val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"type\", t);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tif (!strcmp(\"parameter\", t)) {\n+\t\tmf->type = CPFL_TDI_MOD_FIELD_TYPE_PARAMETER;\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"param_handle\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tmf->param_handle = (uint32_t)val;\n+\t} else if (!strcmp(\"constant\", t)) {\n+\t\tmf->type = CPFL_TDI_MOD_FIELD_TYPE_CONSTANT;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown mod field type %s.\", t);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_field_byte_order(json_t *root, struct cpfl_tdi_mod_field *mf)\n+{\n+\tchar bo[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"byte_order\", bo);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tif (!strcmp(\"HOST\", bo))\n+\t\tmf->byte_order = CPFL_TDI_BYTE_ORDER_HOST;\n+\telse if (!strcmp(\"NETWORK\", bo))\n+\t\tmf->byte_order = CPFL_TDI_BYTE_ORDER_NETWORK;\n+\telse\n+\t\tPMD_DRV_LOG(ERR, \"Unknown byte order type %s.\", bo);\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_field_value(json_t *root, struct cpfl_tdi_mod_field *mf)\n+{\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tif (array_len > CPFL_TDI_VALUE_SIZE_MAX) {\n+\t\tPMD_DRV_LOG(ERR, \"Value array out of bound.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmf->value_size = (uint16_t)array_len;\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tint val;\n+\t\tjson_t *val_obj = json_array_get(root, i);\n+\n+\t\tif (!json_is_integer(val_obj)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Invalid value item, not an integer.\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tval = json_integer_value(val_obj);\n+\t\tmf->value[i] = (uint8_t)val;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_field_obj(json_t *root, struct cpfl_tdi_mod_field *mf)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", mf->name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmf->handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_parse_mod_field_type(root, mf);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_mod_field_byte_order(root, mf);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"byte_array_index\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmf->byte_array_index = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"start_bit_offset\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmf->start_bit_offset = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"bit_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmf->bit_width = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"value\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_mod_field_value(jobj, mf);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_fields(json_t *root, struct cpfl_tdi_mod_content_format *mcf)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tmcf->mod_field_num = (uint16_t)array_len;\n+\tmcf->mod_fields = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_mod_field) * array_len, 0);\n+\tif (mcf->mod_fields == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create mod field array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *mf_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_mod_field_obj(mf_object, &mcf->mod_fields[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_mod_content_format(json_t *root, struct cpfl_tdi_mod_content_format *mcf)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret, val = 0;\n+\n+\tif (json_object_get(root, \"mod_profile\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"mod_profile\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tmcf->mod_profile = (uint16_t)val;\n+\t} else if (json_object_get(root, \"mod_lut_num\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"mod_lut_num\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tmcf->mod_lut_num = (uint16_t)val;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to parse mod_content_format.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"mod_obj_size\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tmcf->mod_obj_size = (uint16_t)val;\n+\n+\tif (json_object_get(root, \"mod_fields\") != NULL) {\n+\t\tret = cpfl_tdi_get_array_obj(root, \"mod_fields\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\treturn cpfl_tdi_parse_mod_fields(jobj, mcf);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_pparse_action_code(json_t *root, struct cpfl_tdi_hw_action *ha)\n+{\n+\tchar ac[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"action_code\", ac);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(ac, \"SET10_1b\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_SET10_1b;\n+\t} else if (!strcmp(ac, \"SET1_16b\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_SET1_16b;\n+\t} else if (!strcmp(ac, \"SET1A_24b\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_SET1A_24b;\n+\t} else if (!strcmp(ac, \"SET1B_24b\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_SET1B_24b;\n+\t} else if (!strcmp(ac, \"SET2_8b\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_SET2_8b;\n+\t} else if (!strcmp(ac, \"NOP\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_NOP;\n+\t} else if (!strcmp(ac, \"AUX_DATA\")) {\n+\t\tha->action_code = CPFL_TDI_ACTION_CODE_AUX_DATA;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown action code type %s\", ac);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_setmd_action_code(json_t *root, struct cpfl_tdi_hw_action *ha)\n+{\n+\tchar ac[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\t/* allow no value */\n+\tif (json_object_get(root, \"setmd_action_code\") == NULL) {\n+\t\tha->setmd_action_code = CPFL_TDI_SETMD_ACTION_CODE_NONE;\n+\t\treturn 0;\n+\t}\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"setmd_action_code\", ac);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(ac, \"SET_8b\")) {\n+\t\tha->setmd_action_code = CPFL_TDI_SETMD_ACTION_CODE_SET_8b;\n+\t} else if (!strcmp(ac, \"SET_16b\")) {\n+\t\tha->setmd_action_code = CPFL_TDI_SETMD_ACTION_CODE_SET_16b;\n+\t} else if (!strcmp(ac, \"SET_32b_AUX\")) {\n+\t\tha->setmd_action_code = CPFL_TDI_SETMD_ACTION_CODE_SET_32b_AUX;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown setmd action code type %s\", ac);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_hw_action_parameter_obj(json_t *root, struct cpfl_tdi_hw_action_parameter *param)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"param_name\", param->param_name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"param_handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tparam->param_handle = (uint32_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_hw_action_parameters(json_t *root, struct cpfl_tdi_hw_action *ha)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tha->parameter_num = (uint16_t)array_len;\n+\tha->parameters =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_hw_action_parameter) * array_len, 0);\n+\tif (ha->parameters == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create hw action parameter array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *p_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_hw_action_parameter_obj(p_object, &ha->parameters[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_hw_action_obj(json_t *root, struct cpfl_tdi_hw_action *ha)\n+{\n+\tint ret, val = 0;\n+\tjson_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"prec\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tha->prec = (uint16_t)val;\n+\n+\tret = cpfl_tdi_pparse_action_code(root, ha);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_setmd_action_code(root, ha);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"index\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tha->index = (uint32_t)val;\n+\n+\tif (json_object_get(root, \"mod_profile\") != NULL) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"mod_profile\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->mod_profile = (uint16_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"prefetch\") != NULL) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"prefetch\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->prefetch = (uint16_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"parameters\") != NULL) {\n+\t\tret = cpfl_tdi_get_array_obj(root, \"parameters\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_hw_action_parameters(jobj, ha);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\tif (json_object_get(root, \"p4_ref_action_handle\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"p4_ref_action_handle\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->p4_ref_action_handle = (uint32_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"p4_ref_table_handle\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"p4_ref_table_handle\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->p4_ref_table_handle = (uint32_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"value\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"value\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->value = (uint16_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"mask\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"mask\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->mask = (uint16_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"type_id\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"type_id\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->type_id = (uint16_t)val;\n+\t}\n+\n+\tif (json_object_get(root, \"offset\")) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"offset\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tha->offset = (uint16_t)val;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_hw_actions_list(json_t *root, struct cpfl_tdi_action_format *af)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\taf->hw_action_num = (uint16_t)array_len;\n+\taf->hw_actions_list = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_hw_action) * array_len, 0);\n+\tif (af->hw_actions_list == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create hw action array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *ha_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_hw_action_obj(ha_object, &af->hw_actions_list[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_action_format_obj(json_t *root, struct cpfl_tdi_action_format *af)\n+{\n+\tint ret, val = 0;\n+\tjson_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"action_name\", af->action_name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"action_handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\taf->action_handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"immediate_fields\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_af_immediate_fields(jobj, af);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tjobj = json_object_get(root, \"mod_content_format\");\n+\tif (jobj != NULL) {\n+\t\tret = cpfl_tdi_parse_mod_content_format(jobj, &af->mod_content_format);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"hw_actions_list\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn cpfl_tdi_parse_hw_actions_list(jobj, af);\n+}\n+\n+static int\n+cpfl_tdi_parse_action_format_array(json_t *root, struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\thb->action_format_num = (uint16_t)array_len;\n+\thb->action_format = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_action_format) * array_len, 0);\n+\tif (hb->action_format == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create action format array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *af_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_action_format_obj(af_object, &hb->action_format[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_act_rams(json_t *root, struct cpfl_tdi_wcm_params *wm)\n+{\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tif (array_len > 16) {\n+\t\tPMD_DRV_LOG(ERR, \"Action ram array out of bound.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tint val;\n+\t\tjson_t *am_obj = json_array_get(root, i);\n+\n+\t\tif (!json_is_integer(am_obj)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Invalid action ram index, not an integer.\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tval = json_integer_value(am_obj);\n+\t\twm->act_rams[i] = (uint8_t)val;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_wcm_params(json_t *root, struct cpfl_tdi_wcm_params *wm)\n+{\n+\tint ret, val = 0;\n+\tjson_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"wcm_group\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\twm->wcm_group = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"slice_start_idx\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\twm->slice_start_idx = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"table_width\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\twm->table_width = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"entry_cnt\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\twm->entry_cnt = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"entry_idx\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\twm->entry_idx = (uint16_t)val;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"act_rams\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn cpfl_tdi_parse_act_rams(jobj, wm);\n+}\n+\n+static int\n+cpfl_tdi_parse_hb_immediate_fields(json_t *root, struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\thb->meter.immediate_field_num = (uint16_t)array_len;\n+\thb->meter.immediate_fields =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_immediate_field) * array_len, 0);\n+\tif (hb->meter.immediate_fields == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to immediate field array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *if_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_immediate_field_obj(if_object, &hb->meter.immediate_fields[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_ma_hardware_block_obj(json_t *root,\n+\t\t\t\t     enum cpfl_tdi_table_type table_type,\n+\t\t\t\t     struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tint ret, val = 0;\n+\tjson_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_parse_ma_hw_block(root, hb);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"id\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\thb->id = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"hw_interface\", hb->hw_interface);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\tif (table_type == CPFL_TDI_TABLE_TYPE_MATCH) {\n+\t\tret = cpfl_tdi_get_array_obj(root, \"profile\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_profiles(jobj, hb);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_get_array_obj(root, \"action_format\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tret = cpfl_tdi_parse_action_format_array(jobj, hb);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\tswitch (hb->hw_block) {\n+\tcase CPFL_TDI_HW_BLOCK_SEM:\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"sub_profile\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\thb->sem.sub_profile = (uint16_t)val;\n+\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"obj_id\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\thb->sem.obj_id = (uint32_t)val;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_WCM:\n+\t\tret = cpfl_tdi_get_object_obj(root, \"wcm_params\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_wcm_params(jobj, &hb->wcm.wcm_params);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_MOD:\n+\t\tret = cpfl_tdi_get_string_obj(root, \"hw_resource\", hb->mod.hw_resource);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"hw_resource_id\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\thb->mod.hw_resource_id = (uint32_t)val;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_METER:\n+\t\tret = cpfl_tdi_get_string_obj(root, \"hw_resource\", hb->mod.hw_resource);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"hw_resource_id\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\thb->mod.hw_resource_id = (uint32_t)val;\n+\t\tret = cpfl_tdi_get_array_obj(root, \"immediate_fields\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_hb_immediate_fields(jobj, hb);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_LEM:\n+\tcase CPFL_TDI_HW_BLOCK_CXP_LEM:\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"hash_size\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\thb->lem.hash_size = (uint16_t)val;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_LPM:\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"max_prefix_len\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\thb->lpm.max_prefix_len = (uint16_t)val;\n+\t\tbreak;\n+\tcase CPFL_TDI_HW_BLOCK_HASH:\n+\t\tbreak;\n+\tdefault:\n+\t\tprintf(\"not support this hardware_block type: %d\\n\", hb->hw_block);\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_ma_hardware_blocks(json_t *root,\n+\t\t\t\t  enum cpfl_tdi_table_type table_type,\n+\t\t\t\t  struct cpfl_tdi_match_attributes *ma)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tma->hardware_block_num = (uint16_t)array_len;\n+\tma->hardware_blocks =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_ma_hardware_block) * array_len, 0);\n+\tif (ma->hardware_blocks == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create match attribute's hardware block array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *hb_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_ma_hardware_block_obj(hb_object, table_type,\n+\t\t\t\t\t\t\t   &ma->hardware_blocks[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_match_attributes(json_t *root,\n+\t\t\t\tenum cpfl_tdi_table_type table_type,\n+\t\t\t\tstruct cpfl_tdi_match_attributes *ma)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"hardware_blocks\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn cpfl_tdi_parse_ma_hardware_blocks(jobj, table_type, ma);\n+}\n+\n+static int\n+cpfl_tdi_parse_table_obj(json_t *root, struct cpfl_tdi_table *table)\n+{\n+\tint ret, val = 0;\n+\tstruct json_t *jobj = NULL;\n+\n+\tret = cpfl_tdi_parse_table_type(root, table);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"handle\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\ttable->handle = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", table->name);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tif (table->table_type == CPFL_TDI_TABLE_TYPE_POLICER_METER) {\n+\t\t/* TODO */\n+\t\treturn 0;\n+\t}\n+\n+\tif (table->table_type == CPFL_TDI_TABLE_TYPE_MATCH) {\n+\t\tret = cpfl_tdi_parse_table_dir(root, table);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tret = cpfl_tdi_get_boolean_obj(root, \"add_on_miss\", &table->add_on_miss);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tret = cpfl_tdi_get_boolean_obj(root, \"idle_timeout_with_auto_delete\",\n+\t\t\t\t\t       &table->idle_timeout_with_auto_delete);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"default_action_handle\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\ttable->default_action_handle = (uint32_t)val;\n+\t\tret = cpfl_tdi_get_array_obj(root, \"actions\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_actions(jobj, table);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t} else if (table->table_type == CPFL_TDI_TABLE_TYPE_MATCH_VALUE_LOOKUP_TABLE) {\n+\t\tret = cpfl_tdi_get_integer_obj(root, \"size\", &val);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\ttable->size = (uint16_t)val;\n+\t\tret = cpfl_tdi_get_boolean_obj(root, \"p4_hidden\", &table->p4_hidden);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"match_key_fields\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_match_key_fields(jobj, table);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tif (json_object_get(root, \"match_key_format\") != NULL) {\n+\t\tret = cpfl_tdi_get_array_obj(root, \"match_key_format\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tret = cpfl_tdi_parse_match_key_format_array(jobj, table);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = cpfl_tdi_get_object_obj(root, \"match_attributes\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tret = cpfl_tdi_parse_match_attributes(jobj, table->table_type, &table->match_attributes);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_tables(json_t *root, struct cpfl_tdi_program *prog)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tprog->table_num = (uint16_t)array_len;\n+\tprog->tables = rte_zmalloc(NULL, sizeof(struct cpfl_tdi_table) * array_len, 0);\n+\tif (prog->tables == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create table array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *table_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_table_obj(table_object, &prog->tables[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_hash_space_cfg(json_t *root, struct cpfl_tdi_hash_space_cfg *cfg)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"base_128_entries\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tcfg->base_128_entries = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"base_256_entries\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tcfg->base_256_entries = (uint32_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_rc_entry_space_cfg(json_t *root, struct cpfl_tdi_rc_entry_space_cfg *cfg)\n+{\n+\tint ret, val = 0;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"rc_num_banks\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tcfg->rc_num_banks = (uint32_t)val;\n+\n+\tret = cpfl_tdi_get_integer_obj(root, \"rc_num_entries\", &val);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tcfg->rc_num_entries = (uint32_t)val;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_gc_hw_block(json_t *root, struct cpfl_tdi_gc_hardware_block *hb)\n+{\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"name\", name);\n+\tif (ret != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!strcmp(name, \"SEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_SEM;\n+\t} else if (!strcmp(name, \"LEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_LEM;\n+\t} else if (!strcmp(name, \"WCM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_WCM;\n+\t} else if (!strcmp(name, \"MOD\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_MOD;\n+\t} else if (!strcmp(name, \"HASH\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_HASH;\n+\t} else if (!strcmp(name, \"RC\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_RC;\n+\t} else if (!strcmp(name, \"CXP_LEM\")) {\n+\t\thb->hw_block = CPFL_TDI_HW_BLOCK_CXP_LEM;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Unknown hardware block type %s\", name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_gc_hardware_block(json_t *root, struct cpfl_tdi_gc_hardware_block *hb)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret;\n+\n+\tret = cpfl_tdi_parse_gc_hw_block(root, hb);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tswitch (hb->hw_block) {\n+\tcase CPFL_TDI_HW_BLOCK_MOD:\n+\t\tret = cpfl_tdi_get_object_obj(root, \"hash_space_cfg\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\treturn cpfl_tdi_parse_hash_space_cfg(jobj, &hb->hash_space_cfg);\n+\tcase CPFL_TDI_HW_BLOCK_RC:\n+\t\tret = cpfl_tdi_get_object_obj(root, \"rc_entry_space_cfg\", &jobj);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t\treturn cpfl_tdi_parse_rc_entry_space_cfg(jobj, &hb->rc_entry_space_cfg);\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_gc_hardware_blocks(json_t *root, struct cpfl_tdi_global_configs *gc)\n+{\n+\tint ret;\n+\tint array_len = json_array_size(root);\n+\n+\tif (array_len == 0)\n+\t\treturn 0;\n+\n+\tgc->hardware_block_num = (uint16_t)array_len;\n+\tgc->hardware_blocks =\n+\t    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_gc_hardware_block) * array_len, 0);\n+\tif (gc->hardware_blocks == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create hardware block array.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (int i = 0; i < array_len; i++) {\n+\t\tjson_t *hb_object = json_array_get(root, i);\n+\n+\t\tret = cpfl_tdi_parse_gc_hardware_block(hb_object, &gc->hardware_blocks[i]);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cpfl_tdi_parse_global_configs(json_t *root, struct cpfl_tdi_global_configs *gc)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"hardware_blocks\", &jobj);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn cpfl_tdi_parse_gc_hardware_blocks(jobj, gc);\n+}\n+\n+int\n+cpfl_tdi_program_create(json_t *root, struct cpfl_tdi_program *prog)\n+{\n+\tjson_t *jobj = NULL;\n+\tint ret;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"program_name\", prog->program_name);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"build_date\", prog->build_date);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"compile_command\", prog->compile_command);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"compiler_version\", prog->compiler_version);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"schema_version\", prog->schema_version);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_string_obj(root, \"target\", prog->target);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_object_obj(root, \"global_configs\", &jobj);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_parse_global_configs(jobj, &prog->global_configs);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_get_array_obj(root, \"tables\", &jobj);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tret = cpfl_tdi_parse_tables(jobj, prog);\n+\tif (ret != 0)\n+\t\tgoto err;\n+\n+\tjson_decref(root);\n+\n+\treturn 0;\n+\n+err:\n+\tcpfl_tdi_program_destroy(prog);\n+\treturn ret;\n+}\n+\n+static void\n+cpfl_tdi_destroy_hw_action(struct cpfl_tdi_hw_action *action)\n+{\n+\tif (action->parameter_num > 0)\n+\t\trte_free(action->parameters);\n+}\n+\n+static void\n+cpfl_tdi_cpfl_tdi_destroy_action_format(struct cpfl_tdi_action_format *format)\n+{\n+\tuint16_t i;\n+\n+\tif (format->immediate_field_num > 0)\n+\t\trte_free(format->immediate_fields);\n+\n+\tif (format->mod_content_format.mod_field_num > 0)\n+\t\trte_free(format->mod_content_format.mod_fields);\n+\n+\tfor (i = 0; i < format->hw_action_num; i++)\n+\t\tcpfl_tdi_destroy_hw_action(&format->hw_actions_list[i]);\n+\n+\tif (format->hw_action_num > 0)\n+\t\trte_free(format->hw_actions_list);\n+}\n+\n+static void\n+cpfl_tdi_destroy_hardware_block(struct cpfl_tdi_ma_hardware_block *hb)\n+{\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < hb->action_format_num; i++)\n+\t\tcpfl_tdi_cpfl_tdi_destroy_action_format(&hb->action_format[i]);\n+\n+\tif (hb->action_format_num > 0)\n+\t\trte_free(hb->action_format);\n+}\n+\n+static void\n+cpfl_tdi_destroy_action(struct cpfl_tdi_action *action)\n+{\n+\tif (action->p4_parameter_num > 0)\n+\t\trte_free(action->p4_parameters);\n+}\n+\n+static void\n+cpfl_tdi_destroy_table(struct cpfl_tdi_table *table)\n+{\n+\tuint16_t i;\n+\n+\tif (table->match_key_field_num > 0)\n+\t\trte_free(table->match_key_fields);\n+\n+\tif (table->match_key_format_num > 0)\n+\t\trte_free(table->match_key_format);\n+\n+\tfor (i = 0; i < table->action_num; i++)\n+\t\tcpfl_tdi_destroy_action(&table->actions[i]);\n+\n+\tif (table->action_num > 0)\n+\t\trte_free(table->actions);\n+\n+\tfor (i = 0; i < table->match_attributes.hardware_block_num; i++)\n+\t\tcpfl_tdi_destroy_hardware_block(&table->match_attributes.hardware_blocks[i]);\n+\n+\tif (table->match_attributes.hardware_block_num > 0)\n+\t\trte_free(table->match_attributes.hardware_blocks);\n+}\n+\n+void\n+cpfl_tdi_program_destroy(struct cpfl_tdi_program *program)\n+{\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < program->table_num; i++)\n+\t\tcpfl_tdi_destroy_table(&program->tables[i]);\n+\n+\tif (program->table_num > 0)\n+\t\trte_free(program->tables);\n+\n+\trte_free(program);\n+}\ndiff --git a/drivers/net/cpfl/cpfl_tdi_parser.h b/drivers/net/cpfl/cpfl_tdi_parser.h\nnew file mode 100644\nindex 0000000000..c3d84adb77\n--- /dev/null\n+++ b/drivers/net/cpfl/cpfl_tdi_parser.h\n@@ -0,0 +1,293 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+#ifndef _CPFL_TDI_PARSER_H_\n+#define _CPFL_TDI_PARSER_H_\n+\n+#include <jansson.h>\n+#include <rte_flow.h>\n+\n+#include \"cpfl_ethdev.h\"\n+\n+#define CPFL_TDI_JSON_STR_SIZE_MAX 100\n+\n+enum cpfl_tdi_table_type {\n+\tCPFL_TDI_TABLE_TYPE_MATCH,\n+\tCPFL_TDI_TABLE_TYPE_MATCH_VALUE_LOOKUP_TABLE,\n+\tCPFL_TDI_TABLE_TYPE_POLICER_METER,\n+};\n+\n+enum cpfl_tdi_table_dir {\n+\tCPFL_TDI_TABLE_DIR_RX,\n+\tCPFL_TDI_TABLE_DIR_TX,\n+\tCPFL_TDI_TABLE_DIR_BI,\n+};\n+\n+enum cpfl_tdi_match_type {\n+\tCPFL_TDI_MATCH_TYPE_EXACT,\n+\tCPFL_TDI_MATCH_TYPE_SELECTOR,\n+\tCPFL_TDI_MATCH_TYPE_TERNARY,\n+\tCPFL_TDI_MATCH_TYPE_LPM,\n+};\n+\n+/**\n+ * Byte order.\n+ *\n+ * To specify the byte order of table key / action field value in bytes.\n+ */\n+enum cpfl_tdi_byte_order {\n+\tCPFL_TDI_BYTE_ORDER_HOST,    /**< follow host byte order. */\n+\tCPFL_TDI_BYTE_ORDER_NETWORK, /**< follow network byte order. */\n+};\n+\n+#define CPFL_TDI_NAME_SIZE_MAX 80\n+\n+struct cpfl_tdi_match_key_format {\n+\tuint32_t match_key_handle;\n+\tenum cpfl_tdi_byte_order byte_order;\n+\tuint16_t byte_array_index;\n+\tuint16_t start_bit_offset;\n+\tuint16_t bit_width;\n+};\n+\n+struct cpfl_tdi_match_key_field {\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar instance_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar field_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tenum cpfl_tdi_match_type match_type;\n+\tuint16_t bit_width;\n+\tuint32_t index;\n+\tuint32_t position;\n+};\n+\n+struct cpfl_tdi_p4_parameter {\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint16_t bit_width;\n+};\n+\n+struct cpfl_tdi_action {\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint32_t handle;\n+\tbool constant_default_action;\n+\tbool is_compiler_added_action;\n+\tbool allowed_as_hit_action;\n+\tbool allowed_as_default_action;\n+\tuint16_t p4_parameter_num;\n+\tstruct cpfl_tdi_p4_parameter *p4_parameters;\n+};\n+\n+struct cpfl_tdi_immediate_field {\n+\tchar param_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint32_t param_handle;\n+\tuint16_t dest_start;\n+\tuint16_t start_bit_offset;\n+\tuint16_t dest_width;\n+};\n+\n+enum cpfl_tdi_mod_field_type {\n+\tCPFL_TDI_MOD_FIELD_TYPE_PARAMETER,\n+\tCPFL_TDI_MOD_FIELD_TYPE_CONSTANT,\n+};\n+\n+#define CPFL_TDI_VALUE_SIZE_MAX 16\n+\n+struct cpfl_tdi_mod_field {\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint32_t handle;\n+\tuint32_t param_handle;\n+\tenum cpfl_tdi_mod_field_type type;\n+\tenum cpfl_tdi_byte_order byte_order;\n+\tuint16_t byte_array_index;\n+\tuint16_t start_bit_offset;\n+\tuint16_t bit_width;\n+\tuint16_t value_size;\n+\tuint8_t value[CPFL_TDI_VALUE_SIZE_MAX];\n+};\n+\n+struct cpfl_tdi_mod_content_format {\n+\tunion {\n+\t\tuint16_t mod_profile;\n+\t\tuint16_t mod_lut_num;\n+\t};\n+\tuint16_t mod_obj_size;\n+\tuint16_t mod_field_num;\n+\tstruct cpfl_tdi_mod_field *mod_fields;\n+};\n+\n+struct cpfl_tdi_hw_action_parameter {\n+\tchar param_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint32_t param_handle;\n+};\n+\n+enum cpfl_tdi_action_code {\n+\tCPFL_TDI_ACTION_CODE_NONE,\n+\tCPFL_TDI_ACTION_CODE_SET10_1b,\n+\tCPFL_TDI_ACTION_CODE_SET1_16b,\n+\tCPFL_TDI_ACTION_CODE_SET1A_24b,\n+\tCPFL_TDI_ACTION_CODE_SET1B_24b,\n+\tCPFL_TDI_ACTION_CODE_SET2_8b,\n+\tCPFL_TDI_ACTION_CODE_NOP,\n+\tCPFL_TDI_ACTION_CODE_AUX_DATA,\n+};\n+\n+enum cpfl_tdi_setmd_action_code {\n+\tCPFL_TDI_SETMD_ACTION_CODE_NONE,\n+\tCPFL_TDI_SETMD_ACTION_CODE_SET_8b,\n+\tCPFL_TDI_SETMD_ACTION_CODE_SET_16b,\n+\tCPFL_TDI_SETMD_ACTION_CODE_SET_32b_AUX,\n+};\n+\n+struct cpfl_tdi_hw_action {\n+\tuint16_t prec;\n+\tenum cpfl_tdi_action_code action_code;\n+\tenum cpfl_tdi_setmd_action_code setmd_action_code;\n+\tuint16_t index;\n+\tuint16_t mod_profile;\n+\tuint16_t prefetch;\n+\tuint16_t parameter_num;\n+\tstruct cpfl_tdi_hw_action_parameter *parameters;\n+\tuint32_t p4_ref_action_handle;\n+\tuint32_t p4_ref_table_handle;\n+\tuint16_t value;\n+\tuint16_t mask;\n+\tuint16_t type_id;\n+\tuint16_t offset;\n+};\n+\n+struct cpfl_tdi_action_format {\n+\tchar action_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint32_t action_handle;\n+\tuint16_t immediate_field_num;\n+\tstruct cpfl_tdi_immediate_field *immediate_fields;\n+\tstruct cpfl_tdi_mod_content_format mod_content_format;\n+\tuint16_t hw_action_num;\n+\tstruct cpfl_tdi_hw_action *hw_actions_list;\n+};\n+\n+enum cpfl_tdi_hw_block {\n+\tCPFL_TDI_HW_BLOCK_SEM,\n+\tCPFL_TDI_HW_BLOCK_LEM,\n+\tCPFL_TDI_HW_BLOCK_WCM,\n+\tCPFL_TDI_HW_BLOCK_LPM,\n+\tCPFL_TDI_HW_BLOCK_MOD,\n+\tCPFL_TDI_HW_BLOCK_METER,\n+\tCPFL_TDI_HW_BLOCK_HASH,\n+\tCPFL_TDI_HW_BLOCK_RC,\n+\tCPFL_TDI_HW_BLOCK_CXP_LEM,\n+};\n+\n+struct cpfl_tdi_wcm_params {\n+\tuint16_t wcm_group;\n+\tuint16_t slice_start_idx;\n+\tuint16_t table_width;\n+\tuint16_t entry_cnt;\n+\tuint16_t entry_idx;\n+\tuint8_t act_rams[16];\n+};\n+\n+struct cpfl_tdi_ma_hardware_block {\n+\tenum cpfl_tdi_hw_block hw_block;\n+\tuint32_t id;\n+\tchar hw_interface[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tuint16_t profile_num;\n+\tuint16_t profile[16];\n+\tuint16_t action_format_num;\n+\tstruct cpfl_tdi_action_format *action_format;\n+\tunion {\n+\t\tstruct {\n+\t\t\tuint16_t sub_profile;\n+\t\t\tuint32_t obj_id;\n+\t\t} sem;\n+\t\tstruct {\n+\t\t\tstruct cpfl_tdi_wcm_params wcm_params;\n+\t\t} wcm;\n+\t\tstruct {\n+\t\t\tchar hw_resource[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\t\t\tuint32_t hw_resource_id;\n+\t\t} mod;\n+\t\tstruct {\n+\t\t\tchar hw_resource[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\t\t\tuint32_t hw_resource_id;\n+\t\t\tuint16_t immediate_field_num;\n+\t\t\tstruct cpfl_tdi_immediate_field *immediate_fields;\n+\t\t} meter;\n+\t\tstruct {\n+\t\t\tuint16_t hash_size;\n+\t\t} lem;\n+\t\tstruct {\n+\t\t\tuint16_t max_prefix_len;\n+\t\t} lpm;\n+\t};\n+};\n+\n+struct cpfl_tdi_match_attributes {\n+\tuint16_t hardware_block_num;\n+\tstruct cpfl_tdi_ma_hardware_block *hardware_blocks;\n+};\n+\n+struct cpfl_tdi_table {\n+\tenum cpfl_tdi_table_type table_type;\n+\tuint32_t handle;\n+\tchar name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tunion {\n+\t\t/* \"table_type\": \"match\" */\n+\t\tstruct {\n+\t\t\tenum cpfl_tdi_table_dir direction;\n+\t\t\tbool add_on_miss;\n+\t\t\tbool idle_timeout_with_auto_delete;\n+\t\t};\n+\t\t/* \"table_type\": \"match_value_lookup_table\" */\n+\t\tstruct {\n+\t\t\tuint16_t size;\n+\t\t\tbool p4_hidden;\n+\t\t};\n+\t};\n+\tuint16_t match_key_field_num;\n+\tstruct cpfl_tdi_match_key_field *match_key_fields;\n+\tuint16_t match_key_format_num;\n+\tstruct cpfl_tdi_match_key_format *match_key_format;\n+\tuint32_t default_action_handle;\n+\tuint16_t action_num;\n+\tstruct cpfl_tdi_action *actions;\n+\tstruct cpfl_tdi_match_attributes match_attributes;\n+};\n+\n+struct cpfl_tdi_hash_space_cfg {\n+\tuint32_t base_128_entries;\n+\tuint32_t base_256_entries;\n+};\n+\n+struct cpfl_tdi_rc_entry_space_cfg {\n+\tuint32_t rc_num_banks;\n+\tuint32_t rc_num_entries;\n+};\n+\n+struct cpfl_tdi_gc_hardware_block {\n+\tenum cpfl_tdi_hw_block hw_block;\n+\tunion {\n+\t\tstruct cpfl_tdi_hash_space_cfg hash_space_cfg;\n+\t\tstruct cpfl_tdi_rc_entry_space_cfg rc_entry_space_cfg;\n+\t};\n+};\n+\n+struct cpfl_tdi_global_configs {\n+\tuint16_t hardware_block_num;\n+\tstruct cpfl_tdi_gc_hardware_block *hardware_blocks;\n+};\n+\n+struct cpfl_tdi_program {\n+\tchar program_name[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar build_date[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar compile_command[2 * CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar compiler_version[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar schema_version[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tchar target[CPFL_TDI_JSON_STR_SIZE_MAX];\n+\tstruct cpfl_tdi_global_configs global_configs;\n+\tuint16_t table_num;\n+\tstruct cpfl_tdi_table *tables;\n+};\n+\n+int cpfl_tdi_program_create(json_t *ob_root, struct cpfl_tdi_program *program);\n+void cpfl_tdi_program_destroy(struct cpfl_tdi_program *program);\n+\n+#endif\ndiff --git a/drivers/net/cpfl/meson.build b/drivers/net/cpfl/meson.build\nindex e4e0e269bd..f948033f1f 100644\n--- a/drivers/net/cpfl/meson.build\n+++ b/drivers/net/cpfl/meson.build\n@@ -47,6 +47,7 @@ if dpdk_conf.has('RTE_HAS_JANSSON')\n             'cpfl_flow_engine_fxp.c',\n             'cpfl_flow_parser.c',\n             'cpfl_fxp_rule.c',\n+            'cpfl_tdi_parser.c',\n     )\n     ext_deps += jansson_dep\n endif\n",
    "prefixes": [
        "1/2"
    ]
}