get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 135640,
    "url": "http://patches.dpdk.org/api/patches/135640/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240102103351.3435716-1-qi.z.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20240102103351.3435716-1-qi.z.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240102103351.3435716-1-qi.z.zhang@intel.com",
    "date": "2024-01-02T10:33:50",
    "name": "[v4,1/2] net/ice: add Tx scheduling tree dump support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ab9404ea7c568c497b820d597898cf698e12bee0",
    "submitter": {
        "id": 504,
        "url": "http://patches.dpdk.org/api/people/504/?format=api",
        "name": "Qi Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240102103351.3435716-1-qi.z.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 30690,
            "url": "http://patches.dpdk.org/api/series/30690/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=30690",
            "date": "2024-01-02T10:33:50",
            "name": "[v4,1/2] net/ice: add Tx scheduling tree dump support",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/30690/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/135640/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/135640/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 B6B89437F7;\n\tTue,  2 Jan 2024 03:12:52 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 9D7A640689;\n\tTue,  2 Jan 2024 03:12:52 +0100 (CET)",
            "from mgamail.intel.com (mgamail.intel.com [198.175.65.11])\n by mails.dpdk.org (Postfix) with ESMTP id F1D97402BE\n for <dev@dpdk.org>; Tue,  2 Jan 2024 03:12:50 +0100 (CET)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 01 Jan 2024 18:12:51 -0800",
            "from dpdk-qzhan15-test02.sh.intel.com ([10.67.115.37])\n by orsmga008.jf.intel.com with ESMTP; 01 Jan 2024 18:12:48 -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=1704161572; x=1735697572;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=vcFKE+6MrijmTwOTmpyA/s4AiiIaDRqoMjjjyNabV70=;\n b=kSxsh0ON2enTh6FcOHS+PIZAgAwwkcNka0QUtem9CFCieeUBPlyiBVEj\n mAMvU0ZUBzHdDlf+/SPpzpbXG20JyYG/Byw7R6lddfEdkGpjtmxkOjtt5\n zW5rtu4A19fQuQvfkcZAEbYRdgtK7fw0zpDLz1ukadsVcUPcvX7jBugS7\n GDW0WDA+kQDRdi/Yr9S9lsUIfKBUhEUBDwe7qqCb4DllJzxntzpp96neb\n TPtVDn0SkAfeO4XrUz9c+mcZ/8qBeG9ilJ3l6UeaaGpdpwT3+pX/bfMIo\n 0zmi+IONAkFbpwVIvXt/OxadMB+VAQvJNpSSwm4hAdlZapFtAfqosPoza Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10940\"; a=\"3601182\"",
            "E=Sophos;i=\"6.04,324,1695711600\";\n   d=\"scan'208\";a=\"3601182\"",
            "E=McAfee;i=\"6600,9927,10940\"; a=\"808381443\"",
            "E=Sophos;i=\"6.04,324,1695711600\"; d=\"scan'208\";a=\"808381443\""
        ],
        "X-ExtLoop1": "1",
        "From": "Qi Zhang <qi.z.zhang@intel.com>",
        "To": "qiming.yang@intel.com,\n\twenjun1.wu@intel.com",
        "Cc": "dev@dpdk.org,\n\tQi Zhang <qi.z.zhang@intel.com>",
        "Subject": "[PATCH v4 1/2] net/ice:  add Tx scheduling tree dump support",
        "Date": "Tue,  2 Jan 2024 05:33:50 -0500",
        "Message-Id": "<20240102103351.3435716-1-qi.z.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.31.1",
        "In-Reply-To": "<20231226185428.3158880-1-qi.z.zhang@intel.com>",
        "References": "<20231226185428.3158880-1-qi.z.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": "Added Testpmd CLI support for dumping Tx scheduling tree.\n\nUsage:\ntestpmd>txsched dump <port_id> <brief|detail> <filename>\n\nThe output file is in \"dot\" format, which can be converted\ninto an image file using Graphviz.\n\n- In \"brief\" mode, all scheduling nodes in the tree are displayed.\n- In \"detail\" mode, each node's configuration parameters are also\n  displayed.\n\nRenamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains\nall CLI support for diagnostic purposes.\n\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\n---\nv4:\n- show node type in brief mode\n\nv3:\n- fix incorrect parameter when query rl profile\n\nv2:\n- fix CI build issue\n\n .../ice/{ice_ddp_package.c => ice_diagnose.c} | 367 ++++++++++++++++++\n drivers/net/ice/ice_ethdev.h                  |   3 +\n drivers/net/ice/ice_testpmd.c                 |  65 ++++\n drivers/net/ice/meson.build                   |   2 +-\n drivers/net/ice/version.map                   |   1 +\n 5 files changed, 437 insertions(+), 1 deletion(-)\n rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (61%)",
    "diff": "diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c\nsimilarity index 61%\nrename from drivers/net/ice/ice_ddp_package.c\nrename to drivers/net/ice/ice_diagnose.c\nindex 0aa19eb282..f259244825 100644\n--- a/drivers/net/ice/ice_ddp_package.c\n+++ b/drivers/net/ice/ice_diagnose.c\n@@ -11,6 +11,7 @@\n #include <rte_tailq.h>\n \n #include \"ice_ethdev.h\"\n+#include \"ice_rxtx.h\"\n \n #define ICE_BLK_MAX_COUNT          512\n #define ICE_BUFF_SEG_HEADER_FLAG   0x1\n@@ -507,3 +508,369 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size)\n \n \treturn ice_dump_switch(dev, buff, size);\n }\n+\n+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,\n+\t\t\t     FILE *stream)\n+{\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t<table>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>id</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>%d</td>\\n\", prof->profile_id);\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>max burst size</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>%d</td>\\n\", prof->max_burst_size);\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>rate limit multiply</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>%d</td>\\n\", prof->rl_multiply);\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>wake up calculation</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>%d</td>\\n\", prof->wake_up_calc);\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>rate limit encode</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t\\t<td>%d</td>\\n\", prof->rl_encode);\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t\\t</table>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t</td>\\n\");\n+}\n+\n+static\n+void print_elem_type(FILE *stream, u8 type)\n+{\n+\tswitch (type) {\n+\tcase 1:\n+\t\tfprintf(stream, \"root\");\n+\t\tbreak;\n+\tcase 2:\n+\t\tfprintf(stream, \"tc\");\n+\t\tbreak;\n+\tcase 3:\n+\t\tfprintf(stream, \"se_generic\");\n+\t\tbreak;\n+\tcase 4:\n+\t\tfprintf(stream, \"entry_point\");\n+\t\tbreak;\n+\tcase 5:\n+\t\tfprintf(stream, \"leaf\");\n+\t\tbreak;\n+\tdefault:\n+\t\tfprintf(stream, \"%d\", type);\n+\t\tbreak;\n+\t}\n+}\n+\n+static\n+void print_valid_sections(FILE *stream, u8 vs)\n+{\n+\tif ((vs & 0x1) != 0)\n+\t\tfprintf(stream, \"generic \");\n+\tif ((vs & 0x2) != 0)\n+\t\tfprintf(stream, \"cir \");\n+\tif ((vs & 0x4) != 0)\n+\t\tfprintf(stream, \"eir \");\n+\tif ((vs & 0x8) != 0)\n+\t\tfprintf(stream, \"shared \");\n+}\n+\n+static\n+void print_scheduling_mode(FILE *stream, bool flag)\n+{\n+\tif (flag)\n+\t\tfprintf(stream, \"pps\");\n+\telse\n+\t\tfprintf(stream, \"bps\");\n+}\n+\n+static\n+void print_priority_mode(FILE *stream, bool flag)\n+{\n+\tif (flag)\n+\t\tfprintf(stream, \"single priority node\");\n+\telse\n+\t\tfprintf(stream, \"wfq\");\n+}\n+\n+static\n+void print_node(struct ice_aqc_txsched_elem_data *data,\n+\t\tstruct ice_aqc_rl_profile_elem *cir_prof,\n+\t\tstruct ice_aqc_rl_profile_elem *eir_prof,\n+\t\tstruct ice_aqc_rl_profile_elem *shared_prof,\n+\t\tbool detail, FILE *stream)\n+{\n+\tfprintf(stream, \"\\tNODE_%d [\\n\", data->node_teid);\n+\tfprintf(stream, \"\\t\\tlabel=<\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t<table>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> teid </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", data->node_teid);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> type </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td>\");\n+\tprint_elem_type(stream, data->data.elem_type);\n+\tfprintf(stream, \"</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tif (!detail)\n+\t\tgoto brief;\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> valid sections </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td>\");\n+\tprint_valid_sections(stream, data->data.valid_sections);\n+\tfprintf(stream,\t\"</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> scheduling mode </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td>\");\n+\tprint_scheduling_mode(stream, (data->data.generic & 0x1) != 0);\n+\tfprintf(stream, \"</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> priority </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", (data->data.generic >> 1) & 0x7);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> priority mode</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td>\");\n+\tprint_priority_mode(stream, ((data->data.generic >> 4) & 0x1) != 0);\n+\tfprintf(stream,\t\"</td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> adjustment value </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", (data->data.generic >> 5) & 0x3);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> suspended </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", data->data.flags & 0x1);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> cir bw profile </td>\\n\");\n+\tif (cir_prof == NULL)\n+\t\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> default </td>\\n\");\n+\telse\n+\t\tprint_rl_profile(cir_prof, stream);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> cir bw weight </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", data->data.cir_bw.bw_alloc);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> eir bw profile </td>\\n\");\n+\tif (eir_prof == NULL)\n+\t\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> default </td>\\n\");\n+\telse\n+\t\tprint_rl_profile(eir_prof, stream);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> eir bw weight </td>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> %d </td>\\n\", data->data.eir_bw.bw_alloc);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t\\t\\t<tr>\\n\");\n+\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> shared rl profile </td>\\n\");\n+\tif (shared_prof == NULL)\n+\t\tfprintf(stream, \"\\t\\t\\t\\t\\t<td> default </td>\\n\");\n+\telse\n+\t\tprint_rl_profile(shared_prof, stream);\n+\tfprintf(stream, \"\\t\\t\\t\\t</tr>\\n\");\n+\n+brief:\n+\tfprintf(stream, \"\\t\\t\\t</table>\\n\");\n+\n+\tfprintf(stream, \"\\t\\t>\\n\");\n+\tfprintf(stream, \"\\t\\tshape=plain\\n\");\n+\tfprintf(stream, \"\\t]\\n\");\n+\n+\tif (data->parent_teid != 0xFFFFFFFF)\n+\t\tfprintf(stream, \"\\tNODE_%d -> NODE_%d\\n\", data->parent_teid, data->node_teid);\n+}\n+\n+static\n+int query_rl_profile(struct ice_hw *hw,\n+\t\t     uint8_t level, uint8_t flags, uint16_t profile_id,\n+\t\t     struct ice_aqc_rl_profile_elem *data)\n+{\n+\tenum ice_status ice_status;\n+\n+\tdata->level = level;\n+\tdata->flags = flags;\n+\tdata->profile_id = profile_id;\n+\n+\tice_status = ice_aq_query_rl_profile(hw, 1, data,\n+\t\t\t\t\t     sizeof(struct ice_aqc_rl_profile_elem), NULL);\n+\n+\tif (ice_status != ICE_SUCCESS) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to query rl profile.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static\n+int query_node(struct ice_hw *hw, uint32_t child, uint32_t *parent,\n+\t       uint8_t level, bool detail, FILE *stream)\n+{\n+\tstruct ice_aqc_txsched_elem_data data;\n+\tenum ice_status status;\n+\tstruct ice_aqc_rl_profile_elem cir_prof;\n+\tstruct ice_aqc_rl_profile_elem eir_prof;\n+\tstruct ice_aqc_rl_profile_elem shared_prof;\n+\tstruct ice_aqc_rl_profile_elem *cp = NULL;\n+\tstruct ice_aqc_rl_profile_elem *ep = NULL;\n+\tstruct ice_aqc_rl_profile_elem *sp = NULL;\n+\tint ret;\n+\n+\t(void)level;\n+\tstatus = ice_sched_query_elem(hw, child, &data);\n+\tif (status != ICE_SUCCESS) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to query scheduling node.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*parent = data.parent_teid;\n+\n+\tif (data.data.cir_bw.bw_profile_idx != 0) {\n+\t\tret = query_rl_profile(hw, level, 0, data.data.cir_bw.bw_profile_idx, &cir_prof);\n+\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tcp = &cir_prof;\n+\t}\n+\n+\tif (data.data.eir_bw.bw_profile_idx != 0) {\n+\t\tret = query_rl_profile(hw, level, 1, data.data.eir_bw.bw_profile_idx, &eir_prof);\n+\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tep = &eir_prof;\n+\t}\n+\n+\tif (data.data.srl_id != 0) {\n+\t\tret = query_rl_profile(hw, level, 2, data.data.srl_id, &shared_prof);\n+\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tsp = &shared_prof;\n+\t}\n+\n+\tprint_node(&data, cp, ep, sp, detail, stream);\n+\n+\treturn 0;\n+}\n+\n+static\n+int query_nodes(struct ice_hw *hw,\n+\t\tuint32_t *children, int child_num,\n+\t\tuint32_t *parents, int *parent_num,\n+\t\tuint8_t level, bool detail,\n+\t\tFILE *stream)\n+{\n+\tuint32_t parent;\n+\tint i;\n+\tint j;\n+\n+\t*parent_num = 0;\n+\tfor (i = 0; i < child_num; i++) {\n+\t\tbool exist = false;\n+\t\tint ret;\n+\n+\t\tret = query_node(hw, children[i], &parent, level, detail, stream);\n+\t\tif (ret)\n+\t\t\treturn -EINVAL;\n+\n+\t\tfor (j = 0; j < *parent_num; j++) {\n+\t\t\tif (parents[j] == parent) {\n+\t\t\t\texist = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!exist && parent != 0xFFFFFFFF)\n+\t\t\tparents[(*parent_num)++] = parent;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tstruct ice_hw *hw;\n+\tstruct ice_pf *pf;\n+\tstruct ice_q_ctx *q_ctx;\n+\tuint16_t q_num;\n+\tuint16_t i;\n+\tstruct ice_tx_queue *txq;\n+\tuint32_t buf1[256];\n+\tuint32_t buf2[256];\n+\tuint32_t *children = buf1;\n+\tuint32_t *parents = buf2;\n+\tint child_num = 0;\n+\tint parent_num = 0;\n+\tuint8_t level;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);\n+\n+\tdev = &rte_eth_devices[port];\n+\tif (!is_ice_supported(dev))\n+\t\treturn -ENOTSUP;\n+\n+\tdev = &rte_eth_devices[port];\n+\thw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tpf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\tlevel = hw->num_tx_sched_layers;\n+\n+\tq_num = dev->data->nb_tx_queues;\n+\n+\t/* main vsi */\n+\tfor (i = 0; i < q_num; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tq_ctx = ice_get_lan_q_ctx(hw, txq->vsi->idx, 0, i);\n+\t\tchildren[child_num++] = q_ctx->q_teid;\n+\t}\n+\n+\t/* fdir vsi */\n+\tq_ctx = ice_get_lan_q_ctx(hw, pf->fdir.fdir_vsi->idx, 0, 0);\n+\tchildren[child_num++] = q_ctx->q_teid;\n+\n+\tfprintf(stream, \"digraph tx_sched {\\n\");\n+\twhile (child_num > 0) {\n+\t\tint ret;\n+\t\tret = query_nodes(hw, children, child_num,\n+\t\t\t\t  parents, &parent_num,\n+\t\t\t\t  level, detail, stream);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tchildren = parents;\n+\t\tchild_num = parent_num;\n+\t\tlevel--;\n+\t}\n+\tfprintf(stream, \"}\\n\");\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h\nindex d607f028e0..1338c80d14 100644\n--- a/drivers/net/ice/ice_ethdev.h\n+++ b/drivers/net/ice/ice_ethdev.h\n@@ -739,4 +739,7 @@ int rte_pmd_ice_dump_package(uint16_t port, uint8_t **buff, uint32_t *size);\n \n __rte_experimental\n int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size);\n+\n+__rte_experimental\n+int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream);\n #endif /* _ICE_ETHDEV_H_ */\ndiff --git a/drivers/net/ice/ice_testpmd.c b/drivers/net/ice/ice_testpmd.c\nindex a7a8d0c53c..98c02d68c6 100644\n--- a/drivers/net/ice/ice_testpmd.c\n+++ b/drivers/net/ice/ice_testpmd.c\n@@ -3,6 +3,7 @@\n  */\n \n #include <stdlib.h>\n+#include <stdio.h>\n \n #include <cmdline_parse_num.h>\n #include <cmdline_parse_string.h>\n@@ -148,6 +149,63 @@ cmdline_parse_inst_t cmd_ddp_dump_switch = {\n \t},\n };\n \n+/* Dump Tx Scheduling Tree configuration, only for ice PF */\n+struct cmd_txsched_dump_result {\n+\tcmdline_fixed_string_t txsched;\n+\tcmdline_fixed_string_t dump;\n+\tportid_t port_id;\n+\tcmdline_fixed_string_t mode;\n+\tchar filepath[];\n+};\n+\n+cmdline_parse_token_string_t cmd_txsched_dump_txsched =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, txsched, \"txsched\");\n+cmdline_parse_token_string_t cmd_txsched_dump_dump =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, dump, \"dump\");\n+cmdline_parse_token_num_t cmd_txsched_dump_port_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_txsched_dump_result, port_id, RTE_UINT16);\n+cmdline_parse_token_string_t cmd_txsched_dump_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, mode, \"brief#detail\");\n+cmdline_parse_token_string_t cmd_txsched_dump_filepath =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, filepath, NULL);\n+\n+static void\n+cmd_txsched_dump_parsed(void *parsed_result,\n+\t\t\t__rte_unused struct cmdline *cl,\n+\t\t\t__rte_unused void *data)\n+{\n+\tstruct cmd_txsched_dump_result *res = parsed_result;\n+\tbool detail = false;\n+\tFILE *fp;\n+\n+\tif (!strcmp(res->mode, \"detail\"))\n+\t\tdetail = true;\n+\n+\tfp = fopen(res->filepath, \"w\");\n+\tif (fp == NULL) {\n+\t\tfprintf(stderr, \"Failed to open file\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (rte_pmd_ice_dump_txsched(res->port_id, detail, fp))\n+\t\tfprintf(stderr, \"Failed to dump Tx scheduring runtime configure.\\n\");\n+\tfclose(fp);\n+}\n+\n+cmdline_parse_inst_t cmd_txsched_dump = {\n+\t.f = cmd_txsched_dump_parsed,\n+\t.data = NULL,\n+\t.help_str = \"txsched dump <port_id> <brief|detail> <config_path>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_txsched_dump_txsched,\n+\t\t(void *)&cmd_txsched_dump_dump,\n+\t\t(void *)&cmd_txsched_dump_port_id,\n+\t\t(void *)&cmd_txsched_dump_mode,\n+\t\t(void *)&cmd_txsched_dump_filepath,\n+\t\tNULL,\n+\t},\n+};\n+\n static struct testpmd_driver_commands ice_cmds = {\n \t.commands = {\n \t{\n@@ -161,8 +219,15 @@ static struct testpmd_driver_commands ice_cmds = {\n \t\t\"ddp dump switch (port_id) (config_path)\\n\"\n \t\t\"    Dump a runtime switch configure on a port\\n\\n\",\n \n+\t},\n+\t{\n+\t\t&cmd_txsched_dump,\n+\t\t\"txsched dump (port_id) <brief|detail> (config_path)\\n\"\n+\t\t\"    Dump tx scheduling runtime configure on a port\\n\\n\",\n+\n \t},\n \t{ NULL, NULL },\n \t},\n };\n+\n TESTPMD_ADD_DRIVER_COMMANDS(ice_cmds)\ndiff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build\nindex a957fc5d3a..b7f2188e62 100644\n--- a/drivers/net/ice/meson.build\n+++ b/drivers/net/ice/meson.build\n@@ -6,7 +6,7 @@ objs = [base_objs]\n \n sources = files(\n         'ice_acl_filter.c',\n-        'ice_ddp_package.c',\n+        'ice_diagnose.c',\n         'ice_ethdev.c',\n         'ice_fdir_filter.c',\n         'ice_generic_flow.c',\ndiff --git a/drivers/net/ice/version.map b/drivers/net/ice/version.map\nindex 4e924c8f4d..24b425d6f7 100644\n--- a/drivers/net/ice/version.map\n+++ b/drivers/net/ice/version.map\n@@ -8,4 +8,5 @@ EXPERIMENTAL {\n \t# added in 19.11\n \trte_pmd_ice_dump_package;\n \trte_pmd_ice_dump_switch;\n+\trte_pmd_ice_dump_txsched;\n };\n",
    "prefixes": [
        "v4",
        "1/2"
    ]
}