get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 88145,
    "url": "http://patches.dpdk.org/api/patches/88145/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210224124311.29799-9-hemant.agrawal@nxp.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": "<20210224124311.29799-9-hemant.agrawal@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210224124311.29799-9-hemant.agrawal@nxp.com",
    "date": "2021-02-24T12:42:56",
    "name": "[v3,08/23] net/dpaa2: add traffic management driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "d2b533261a9dbd4d207b7ea679a092f61d3daede",
    "submitter": {
        "id": 477,
        "url": "http://patches.dpdk.org/api/people/477/?format=api",
        "name": "Hemant Agrawal",
        "email": "hemant.agrawal@nxp.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210224124311.29799-9-hemant.agrawal@nxp.com/mbox/",
    "series": [
        {
            "id": 15361,
            "url": "http://patches.dpdk.org/api/series/15361/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=15361",
            "date": "2021-02-24T12:42:48",
            "name": "NXP DPAAx ethernet PMD changes",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/15361/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/88145/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/88145/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 1E4ABA034F;\n\tWed, 24 Feb 2021 13:44:33 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4B35B160878;\n\tWed, 24 Feb 2021 13:43:33 +0100 (CET)",
            "from inva020.nxp.com (inva020.nxp.com [92.121.34.13])\n by mails.dpdk.org (Postfix) with ESMTP id 04EEA160837\n for <dev@dpdk.org>; Wed, 24 Feb 2021 13:43:25 +0100 (CET)",
            "from inva020.nxp.com (localhost [127.0.0.1])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id C86C31A039A;\n Wed, 24 Feb 2021 13:43:24 +0100 (CET)",
            "from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com\n [165.114.16.14])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id F398C1A0398;\n Wed, 24 Feb 2021 13:43:21 +0100 (CET)",
            "from bf-netperf1.ap.freescale.net (bf-netperf1.ap.freescale.net\n [10.232.133.63])\n by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id B36A84032A;\n Wed, 24 Feb 2021 13:43:18 +0100 (CET)"
        ],
        "From": "Hemant Agrawal <hemant.agrawal@nxp.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com,\n\tGagandeep Singh <g.singh@nxp.com>",
        "Date": "Wed, 24 Feb 2021 18:12:56 +0530",
        "Message-Id": "<20210224124311.29799-9-hemant.agrawal@nxp.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20210224124311.29799-1-hemant.agrawal@nxp.com>",
        "References": "<20210211141620.12482-1-hemant.agrawal@nxp.com>\n <20210224124311.29799-1-hemant.agrawal@nxp.com>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "Subject": "[dpdk-dev] [PATCH v3 08/23] net/dpaa2: add traffic management driver",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Gagandeep Singh <g.singh@nxp.com>\n\nAdd basic support for scheduling and shaping on dpaa2\nplatform.\n\nHW supports 2 level of scheduling and shaping.\nHowever the current patch only support single level.\n\nSigned-off-by: Gagandeep Singh <g.singh@nxp.com>\nAcked-by: Hemant Agrawal <hemant.agrawal@nxp.com>\n---\n doc/guides/nics/dpaa2.rst           | 120 +++++-\n drivers/net/dpaa2/dpaa2_ethdev.c    |  14 +-\n drivers/net/dpaa2/dpaa2_ethdev.h    |   5 +\n drivers/net/dpaa2/dpaa2_tm.c        | 630 ++++++++++++++++++++++++++++\n drivers/net/dpaa2/dpaa2_tm.h        |  32 ++\n drivers/net/dpaa2/mc/dpni.c         | 313 +++++++++++++-\n drivers/net/dpaa2/mc/fsl_dpni.h     | 210 +++++++++-\n drivers/net/dpaa2/mc/fsl_dpni_cmd.h |  59 ++-\n drivers/net/dpaa2/meson.build       |   3 +-\n 9 files changed, 1380 insertions(+), 6 deletions(-)\n create mode 100644 drivers/net/dpaa2/dpaa2_tm.c\n create mode 100644 drivers/net/dpaa2/dpaa2_tm.h",
    "diff": "diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst\nindex 233d926e0a..893e87e714 100644\n--- a/doc/guides/nics/dpaa2.rst\n+++ b/doc/guides/nics/dpaa2.rst\n@@ -1,5 +1,5 @@\n ..  SPDX-License-Identifier: BSD-3-Clause\n-    Copyright 2016,2020 NXP\n+    Copyright 2016,2020-2021 NXP\n \n \n DPAA2 Poll Mode Driver\n@@ -406,6 +406,8 @@ Features of the DPAA2 PMD are:\n - Jumbo frames\n - Link flow control\n - Scattered and gather for TX and RX\n+- :ref:`Traffic Management API <dptmapi>`\n+\n \n Supported DPAA2 SoCs\n --------------------\n@@ -548,3 +550,119 @@ Other Limitations\n \n - RSS hash key cannot be modified.\n - RSS RETA cannot be configured.\n+\n+.. _dptmapi:\n+\n+Traffic Management API\n+----------------------\n+\n+DPAA2 PMD supports generic DPDK Traffic Management API which allows to\n+configure the following features:\n+\n+1. Hierarchical scheduling\n+2. Traffic shaping\n+\n+Internally TM is represented by a hierarchy (tree) of nodes.\n+Node which has a parent is called a leaf whereas node without\n+parent is called a non-leaf (root).\n+\n+Nodes hold following types of settings:\n+\n+- for egress scheduler configuration: weight\n+- for egress rate limiter: private shaper\n+\n+Hierarchy is always constructed from the top, i.e first a root node is added\n+then some number of leaf nodes. Number of leaf nodes cannot exceed number\n+of configured tx queues.\n+\n+After hierarchy is complete it can be committed.\n+\n+For an additional description please refer to DPDK :doc:`Traffic Management API <../prog_guide/traffic_management>`.\n+\n+Supported Features\n+~~~~~~~~~~~~~~~~~~\n+\n+The following capabilities are supported:\n+\n+- Level0 (root node) and Level1 are supported.\n+- 1 private shaper at root node (port level) is supported.\n+- 8 TX queues per port supported (1 channel per port)\n+- Both SP and WFQ scheduling mechanisms are supported on all 8 queues.\n+- Congestion notification is supported. It means if there is congestion on\n+    the network, DPDK driver will not enqueue any packet (no taildrop or WRED)\n+\n+  User can also check node, level capabilities using testpmd commands.\n+\n+Usage example\n+~~~~~~~~~~~~~\n+\n+For a detailed usage description please refer to \"Traffic Management\" section in DPDK :doc:`Testpmd Runtime Functions <../testpmd_app_ug/testpmd_funcs>`.\n+\n+1. Run testpmd as follows:\n+\n+   .. code-block:: console\n+\n+\t./dpdk-testpmd  -c 0xf -n 1 -- -i --portmask 0x3 --nb-cores=1 --txq=4 --rxq=4\n+\n+2. Stop all ports:\n+\n+   .. code-block:: console\n+\n+\ttestpmd> port stop all\n+\n+3. Add shaper profile:\n+\n+   One port level shaper and strict priority on all 4 queues of port 0:\n+\n+   .. code-block:: console\n+\n+\tadd port tm node shaper profile 0 1 104857600 64 100 0 0\n+\tadd port tm nonleaf node 0 8 -1 0 1 0 1 1 1 0\n+\tadd port tm leaf node 0 0 8 0 1 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 1 8 1 1 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 2 8 2 1 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 3 8 3 1 1 -1 0 0 0 0\n+\tport tm hierarchy commit 0 no\n+\n+\tor\n+\n+   One port level shaper and WFQ on all 4 queues of port 0:\n+\n+   .. code-block:: console\n+\n+\tadd port tm node shaper profile 0 1 104857600 64 100 0 0\n+\tadd port tm nonleaf node 0 8 -1 0 1 0 1 1 1 0\n+\tadd port tm leaf node 0 0 8 0 200 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 1 8 0 300 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 2 8 0 400 1 -1 0 0 0 0\n+\tadd port tm leaf node 0 3 8 0 500 1 -1 0 0 0 0\n+\tport tm hierarchy commit 0 no\n+\n+4. Create flows as per the source IP addresses:\n+\n+   .. code-block:: console\n+\n+\tflow create 1 group 0 priority 1 ingress pattern ipv4 src is \\\n+\t10.10.10.1 / end actions queue index 0 / end\n+\tflow create 1 group 0 priority 2 ingress pattern ipv4 src is \\\n+\t10.10.10.2 / end actions queue index 1 / end\n+\tflow create 1 group 0 priority 3 ingress pattern ipv4 src is \\\n+\t10.10.10.3 / end actions queue index 2 / end\n+\tflow create 1 group 0 priority 4 ingress pattern ipv4 src is \\\n+\t10.10.10.4 / end actions queue index 3 / end\n+\n+5. Start all ports\n+\n+   .. code-block:: console\n+\n+\ttestpmd> port start all\n+\n+\n+\n+6. Enable forwarding\n+\n+   .. code-block:: console\n+\n+\t\ttestpmd> start\n+\n+7. Inject the traffic on port1 as per the configured flows, you will see shaped and scheduled forwarded traffic on port0\ndiff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c\nindex a81c73438e..490eb4b3f4 100644\n--- a/drivers/net/dpaa2/dpaa2_ethdev.c\n+++ b/drivers/net/dpaa2/dpaa2_ethdev.c\n@@ -1,7 +1,7 @@\n /* * SPDX-License-Identifier: BSD-3-Clause\n  *\n  *   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.\n- *   Copyright 2016-2020 NXP\n+ *   Copyright 2016-2021 NXP\n  *\n  */\n \n@@ -638,6 +638,8 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)\n \tif (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)\n \t\tdpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);\n \n+\tdpaa2_tm_init(dev);\n+\n \treturn 0;\n }\n \n@@ -1264,6 +1266,7 @@ dpaa2_dev_close(struct rte_eth_dev *dev)\n \t\treturn -1;\n \t}\n \n+\tdpaa2_tm_deinit(dev);\n \tdpaa2_flow_clean(dev);\n \t/* Clean the device first */\n \tret = dpni_reset(dpni, CMD_PRI_LOW, priv->token);\n@@ -2345,6 +2348,14 @@ dpaa2_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n \tqinfo->conf.tx_deferred_start = 0;\n }\n \n+static int\n+dpaa2_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *ops)\n+{\n+\t*(const void **)ops = &dpaa2_tm_ops;\n+\n+\treturn 0;\n+}\n+\n static struct eth_dev_ops dpaa2_ethdev_ops = {\n \t.dev_configure\t  = dpaa2_eth_dev_configure,\n \t.dev_start\t      = dpaa2_dev_start,\n@@ -2387,6 +2398,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {\n \t.filter_ctrl          = dpaa2_dev_flow_ctrl,\n \t.rxq_info_get\t      = dpaa2_rxq_info_get,\n \t.txq_info_get\t      = dpaa2_txq_info_get,\n+\t.tm_ops_get\t      = dpaa2_tm_ops_get,\n #if defined(RTE_LIBRTE_IEEE1588)\n \t.timesync_enable      = dpaa2_timesync_enable,\n \t.timesync_disable     = dpaa2_timesync_disable,\ndiff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h\nindex bb49fa9a38..9837eb62c8 100644\n--- a/drivers/net/dpaa2/dpaa2_ethdev.h\n+++ b/drivers/net/dpaa2/dpaa2_ethdev.h\n@@ -12,6 +12,7 @@\n #include <rte_pmd_dpaa2.h>\n \n #include <dpaa2_hw_pvt.h>\n+#include \"dpaa2_tm.h\"\n \n #include <mc/fsl_dpni.h>\n #include <mc/fsl_mc_sys.h>\n@@ -112,6 +113,8 @@ extern int dpaa2_timestamp_dynfield_offset;\n extern const struct rte_flow_ops dpaa2_flow_ops;\n extern enum rte_filter_type dpaa2_filter_type;\n \n+extern const struct rte_tm_ops dpaa2_tm_ops;\n+\n #define IP_ADDRESS_OFFSET_INVALID (-1)\n \n struct dpaa2_key_info {\n@@ -179,6 +182,8 @@ struct dpaa2_dev_priv {\n \tstruct rte_eth_dev *eth_dev; /**< Pointer back to holding ethdev */\n \n \tLIST_HEAD(, rte_flow) flows; /**< Configured flow rule handles. */\n+\tLIST_HEAD(nodes, dpaa2_tm_node) nodes;\n+\tLIST_HEAD(shaper_profiles, dpaa2_tm_shaper_profile) shaper_profiles;\n };\n \n int dpaa2_distset_to_dpkg_profile_cfg(uint64_t req_dist_set,\ndiff --git a/drivers/net/dpaa2/dpaa2_tm.c b/drivers/net/dpaa2/dpaa2_tm.c\nnew file mode 100644\nindex 0000000000..f5faaedfb4\n--- /dev/null\n+++ b/drivers/net/dpaa2/dpaa2_tm.c\n@@ -0,0 +1,630 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2020 NXP\n+ */\n+\n+#include <rte_ethdev.h>\n+#include <rte_malloc.h>\n+#include <rte_tm_driver.h>\n+\n+#include \"dpaa2_ethdev.h\"\n+\n+#define DPAA2_BURST_MAX\t(64 * 1024)\n+\n+#define DPAA2_SHAPER_MIN_RATE 0\n+#define DPAA2_SHAPER_MAX_RATE 107374182400ull\n+#define DPAA2_WEIGHT_MAX 24701\n+\n+int\n+dpaa2_tm_init(struct rte_eth_dev *dev)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\n+\tLIST_INIT(&priv->shaper_profiles);\n+\tLIST_INIT(&priv->nodes);\n+\n+\treturn 0;\n+}\n+\n+void dpaa2_tm_deinit(struct rte_eth_dev *dev)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_shaper_profile *profile =\n+\t\tLIST_FIRST(&priv->shaper_profiles);\n+\tstruct dpaa2_tm_node *node = LIST_FIRST(&priv->nodes);\n+\n+\twhile (profile) {\n+\t\tstruct dpaa2_tm_shaper_profile *next = LIST_NEXT(profile, next);\n+\n+\t\tLIST_REMOVE(profile, next);\n+\t\trte_free(profile);\n+\t\tprofile = next;\n+\t}\n+\n+\twhile (node) {\n+\t\tstruct dpaa2_tm_node *next = LIST_NEXT(node, next);\n+\n+\t\tLIST_REMOVE(node, next);\n+\t\trte_free(node);\n+\t\tnode = next;\n+\t}\n+}\n+\n+static struct dpaa2_tm_node *\n+dpaa2_node_from_id(struct dpaa2_dev_priv *priv, uint32_t node_id)\n+{\n+\tstruct dpaa2_tm_node *node;\n+\n+\tLIST_FOREACH(node, &priv->nodes, next)\n+\t\tif (node->id == node_id)\n+\t\t\treturn node;\n+\n+\treturn NULL;\n+}\n+\n+static int\n+dpaa2_capabilities_get(struct rte_eth_dev *dev,\n+\t\t       struct rte_tm_capabilities *cap,\n+\t\t      struct rte_tm_error *error)\n+{\n+\tif (!cap)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, \"Capabilities are NULL\\n\");\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\t/* root node(port) + txqs number, assuming each TX\n+\t * Queue is mapped to each TC\n+\t */\n+\tcap->n_nodes_max = 1 + dev->data->nb_tx_queues;\n+\tcap->n_levels_max = 2; /* port level + txqs level */\n+\tcap->non_leaf_nodes_identical = 1;\n+\tcap->leaf_nodes_identical = 1;\n+\n+\tcap->shaper_n_max = 1;\n+\tcap->shaper_private_n_max = 1;\n+\tcap->shaper_private_dual_rate_n_max = 1;\n+\tcap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;\n+\tcap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;\n+\n+\tcap->sched_n_children_max = dev->data->nb_tx_queues;\n+\tcap->sched_sp_n_priorities_max = dev->data->nb_tx_queues;\n+\tcap->sched_wfq_n_children_per_group_max = dev->data->nb_tx_queues;\n+\tcap->sched_wfq_n_groups_max = 2;\n+\tcap->sched_wfq_weight_max = DPAA2_WEIGHT_MAX;\n+\n+\tcap->dynamic_update_mask = RTE_TM_UPDATE_NODE_STATS;\n+\tcap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_level_capabilities_get(struct rte_eth_dev *dev,\n+\t\t\t    uint32_t level_id,\n+\t\t\t    struct rte_tm_level_capabilities *cap,\n+\t\t\t    struct rte_tm_error *error)\n+{\n+\tif (!cap)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\tif (level_id > 1)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_LEVEL_ID,\n+\t\t\t\t\t NULL, \"Wrong level id\\n\");\n+\n+\tif (level_id == 0) { /* Root node */\n+\t\tcap->n_nodes_max = 1;\n+\t\tcap->n_nodes_nonleaf_max = 1;\n+\t\tcap->non_leaf_nodes_identical = 1;\n+\n+\t\tcap->nonleaf.shaper_private_supported = 1;\n+\t\tcap->nonleaf.shaper_private_dual_rate_supported = 1;\n+\t\tcap->nonleaf.shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;\n+\t\tcap->nonleaf.shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;\n+\n+\t\tcap->nonleaf.sched_n_children_max = dev->data->nb_tx_queues;\n+\t\tcap->nonleaf.sched_sp_n_priorities_max = 1;\n+\t\tcap->nonleaf.sched_wfq_n_children_per_group_max =\n+\t\t\tdev->data->nb_tx_queues;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 2;\n+\t\tcap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX;\n+\t\tcap->nonleaf.stats_mask = RTE_TM_STATS_N_PKTS |\n+\t\t\t\t\t  RTE_TM_STATS_N_BYTES;\n+\t} else { /* leaf nodes */\n+\t\tcap->n_nodes_max = dev->data->nb_tx_queues;\n+\t\tcap->n_nodes_leaf_max = dev->data->nb_tx_queues;\n+\t\tcap->leaf_nodes_identical = 1;\n+\n+\t\tcap->leaf.stats_mask = RTE_TM_STATS_N_PKTS;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_node_capabilities_get(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t\t    struct rte_tm_node_capabilities *cap,\n+\t\t\t   struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_tm_node *node;\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\n+\tif (!cap)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\tnode = dpaa2_node_from_id(priv, node_id);\n+\tif (!node)\n+\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\t\t NULL, \"Node id does not exist\\n\");\n+\n+\tif (node->type == 0) {\n+\t\tcap->shaper_private_supported = 1;\n+\n+\t\tcap->nonleaf.sched_n_children_max = dev->data->nb_tx_queues;\n+\t\tcap->nonleaf.sched_sp_n_priorities_max = 1;\n+\t\tcap->nonleaf.sched_wfq_n_children_per_group_max =\n+\t\t\tdev->data->nb_tx_queues;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 2;\n+\t\tcap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX;\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;\n+\t} else {\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, int *is_leaf,\n+\t\t    struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_node *node;\n+\n+\tif (!is_leaf)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tnode = dpaa2_node_from_id(priv, node_id);\n+\tif (!node)\n+\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\t\t NULL, \"Node id does not exist\\n\");\n+\n+\t*is_leaf = node->type == 1/*NODE_QUEUE*/ ? 1 : 0;\n+\n+\treturn 0;\n+}\n+\n+static struct dpaa2_tm_shaper_profile *\n+dpaa2_shaper_profile_from_id(struct dpaa2_dev_priv *priv,\n+\t\t\t\tuint32_t shaper_profile_id)\n+{\n+\tstruct dpaa2_tm_shaper_profile *profile;\n+\n+\tLIST_FOREACH(profile, &priv->shaper_profiles, next)\n+\t\tif (profile->id == shaper_profile_id)\n+\t\t\treturn profile;\n+\n+\treturn NULL;\n+}\n+\n+static int\n+dpaa2_shaper_profile_add(struct rte_eth_dev *dev, uint32_t shaper_profile_id,\n+\t\t\t struct rte_tm_shaper_params *params,\n+\t\t\tstruct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_shaper_profile *profile;\n+\n+\tif (!params)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\tif (params->committed.rate > DPAA2_SHAPER_MAX_RATE)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,\n+\t\t\t\tNULL, \"committed rate is out of range\\n\");\n+\n+\tif (params->committed.size > DPAA2_BURST_MAX)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,\n+\t\t\t\tNULL, \"committed size is out of range\\n\");\n+\n+\tif (params->peak.rate > DPAA2_SHAPER_MAX_RATE)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,\n+\t\t\t\tNULL, \"Peak rate is out of range\\n\");\n+\n+\tif (params->peak.size > DPAA2_BURST_MAX)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,\n+\t\t\t\tNULL, \"Peak size is out of range\\n\");\n+\n+\tif (shaper_profile_id == RTE_TM_SHAPER_PROFILE_ID_NONE)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,\n+\t\t\t\t\t NULL, \"Wrong shaper profile id\\n\");\n+\n+\tprofile = dpaa2_shaper_profile_from_id(priv, shaper_profile_id);\n+\tif (profile)\n+\t\treturn -rte_tm_error_set(error, EEXIST,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,\n+\t\t\t\t\t NULL, \"Profile id already exists\\n\");\n+\n+\tprofile = rte_zmalloc_socket(NULL, sizeof(*profile), 0,\n+\t\t\t\t     rte_socket_id());\n+\tif (!profile)\n+\t\treturn -rte_tm_error_set(error, ENOMEM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tprofile->id = shaper_profile_id;\n+\trte_memcpy(&profile->params, params, sizeof(profile->params));\n+\n+\tLIST_INSERT_HEAD(&priv->shaper_profiles, profile, next);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_shaper_profile_delete(struct rte_eth_dev *dev, uint32_t shaper_profile_id,\n+\t\t\t    struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_shaper_profile *profile;\n+\n+\tprofile = dpaa2_shaper_profile_from_id(priv, shaper_profile_id);\n+\tif (!profile)\n+\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,\n+\t\t\t\t\t NULL, \"Profile id does not exist\\n\");\n+\n+\tif (profile->refcnt)\n+\t\treturn -rte_tm_error_set(error, EPERM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,\n+\t\t\t\t\t NULL, \"Profile is used\\n\");\n+\n+\tLIST_REMOVE(profile, next);\n+\trte_free(profile);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_node_check_params(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t__rte_unused uint32_t priority, uint32_t weight,\n+\t\t       uint32_t level_id,\n+\t\t       struct rte_tm_node_params *params,\n+\t\t       struct rte_tm_error *error)\n+{\n+\tif (node_id == RTE_TM_NODE_ID_NULL)\n+\t\treturn -rte_tm_error_set(error, EINVAL, RTE_TM_NODE_ID_NULL,\n+\t\t\t\t\t NULL, \"Node id is invalid\\n\");\n+\n+\tif (weight > DPAA2_WEIGHT_MAX)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_WEIGHT,\n+\t\t\t\t\t NULL, \"Weight is out of range\\n\");\n+\n+\tif (level_id != 0 && level_id != 1)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_LEVEL_ID,\n+\t\t\t\t\t NULL, \"Wrong level id\\n\");\n+\n+\tif (!params)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tif (params->shared_shaper_id)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID,\n+\t\t\t\tNULL, \"Shared shaper is not supported\\n\");\n+\n+\tif (params->n_shared_shapers)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS,\n+\t\t\t\tNULL, \"Shared shaper is not supported\\n\");\n+\n+\t/* verify port (root node) settings */\n+\tif (node_id >= dev->data->nb_tx_queues) {\n+\t\tif (params->nonleaf.wfq_weight_mode)\n+\t\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE,\n+\t\t\t\tNULL, \"WFQ weight mode is not supported\\n\");\n+\n+\t\tif (params->stats_mask & ~(RTE_TM_STATS_N_PKTS |\n+\t\t\t\t\t   RTE_TM_STATS_N_BYTES))\n+\t\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_STATS,\n+\t\t\t\tNULL,\n+\t\t\t\t\"Requested port stats are not supported\\n\");\n+\n+\t\treturn 0;\n+\t}\n+\tif (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID,\n+\t\t\tNULL, \"Private shaper not supported on leaf\\n\");\n+\n+\tif (params->stats_mask & ~RTE_TM_STATS_N_PKTS)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_STATS,\n+\t\t\tNULL,\n+\t\t\t\"Requested stats are not supported\\n\");\n+\n+\t/* check leaf node */\n+\tif (level_id == 1) {\n+\t\tif (params->leaf.cman != RTE_TM_CMAN_TAIL_DROP)\n+\t\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN,\n+\t\t\t\t\tNULL, \"Only taildrop is supported\\n\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_node_add(struct rte_eth_dev *dev, uint32_t node_id,\n+\t      uint32_t parent_node_id, uint32_t priority, uint32_t weight,\n+\t      uint32_t level_id, struct rte_tm_node_params *params,\n+\t      struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_shaper_profile *profile = NULL;\n+\tstruct dpaa2_tm_node *node, *parent = NULL;\n+\tint ret;\n+\n+\tif (0/* If device is started*/)\n+\t\treturn -rte_tm_error_set(error, EPERM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, \"Port is already started\\n\");\n+\n+\tret = dpaa2_node_check_params(dev, node_id, priority, weight, level_id,\n+\t\t\t\t      params, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) {\n+\t\tprofile = dpaa2_shaper_profile_from_id(priv,\n+\t\t\t\t\t\t     params->shaper_profile_id);\n+\t\tif (!profile)\n+\t\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,\n+\t\t\t\t\tNULL, \"Shaper id does not exist\\n\");\n+\t}\n+\tif (parent_node_id == RTE_TM_NODE_ID_NULL) {\n+\t\tLIST_FOREACH(node, &priv->nodes, next) {\n+\t\t\tif (node->type != 0 /*root node*/)\n+\t\t\t\tcontinue;\n+\n+\t\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t\t NULL, \"Root node exists\\n\");\n+\t\t}\n+\t} else {\n+\t\tparent = dpaa2_node_from_id(priv, parent_node_id);\n+\t\tif (!parent)\n+\t\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,\n+\t\t\t\t\tNULL, \"Parent node id not exist\\n\");\n+\t}\n+\n+\tnode = dpaa2_node_from_id(priv, node_id);\n+\tif (node)\n+\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\t\t NULL, \"Node id already exists\\n\");\n+\n+\tnode = rte_zmalloc_socket(NULL, sizeof(*node), 0, rte_socket_id());\n+\tif (!node)\n+\t\treturn -rte_tm_error_set(error, ENOMEM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, NULL);\n+\n+\tnode->id = node_id;\n+\tnode->type = parent_node_id == RTE_TM_NODE_ID_NULL ? 0/*NODE_PORT*/ :\n+\t\t\t\t\t\t\t     1/*NODE_QUEUE*/;\n+\n+\tif (parent) {\n+\t\tnode->parent = parent;\n+\t\tparent->refcnt++;\n+\t}\n+\n+\tif (profile) {\n+\t\tnode->profile = profile;\n+\t\tprofile->refcnt++;\n+\t}\n+\n+\tnode->weight = weight;\n+\tnode->priority = priority;\n+\tnode->stats_mask = params->stats_mask;\n+\n+\tLIST_INSERT_HEAD(&priv->nodes, node, next);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_node_delete(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t  struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_node *node;\n+\n+\tif (0) {\n+\t\treturn -rte_tm_error_set(error, EPERM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t NULL, \"Port is already started\\n\");\n+\t}\n+\n+\tnode = dpaa2_node_from_id(priv, node_id);\n+\tif (!node)\n+\t\treturn -rte_tm_error_set(error, ENODEV,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\t\t NULL, \"Node id does not exist\\n\");\n+\n+\tif (node->refcnt)\n+\t\treturn -rte_tm_error_set(error, EPERM,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\t\t NULL, \"Node id is used\\n\");\n+\n+\tif (node->parent)\n+\t\tnode->parent->refcnt--;\n+\n+\tif (node->profile)\n+\t\tnode->profile->refcnt--;\n+\n+\tLIST_REMOVE(node, next);\n+\trte_free(node);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dpaa2_hierarchy_commit(struct rte_eth_dev *dev, int clear_on_fail,\n+\t\t       struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_node *node, *temp_node;\n+\tstruct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;\n+\tint ret;\n+\tint wfq_grp = 0, is_wfq_grp = 0, conf[DPNI_MAX_TC];\n+\tstruct dpni_tx_priorities_cfg prio_cfg;\n+\n+\tmemset(&prio_cfg, 0, sizeof(prio_cfg));\n+\tmemset(conf, 0, sizeof(conf));\n+\n+\tLIST_FOREACH(node, &priv->nodes, next) {\n+\t\tif (node->type == 0/*root node*/) {\n+\t\t\tif (!node->profile)\n+\t\t\t\tcontinue;\n+\n+\t\t\tstruct dpni_tx_shaping_cfg tx_cr_shaper, tx_er_shaper;\n+\n+\t\t\ttx_cr_shaper.max_burst_size =\n+\t\t\t\tnode->profile->params.committed.size;\n+\t\t\ttx_cr_shaper.rate_limit =\n+\t\t\t\tnode->profile->params.committed.rate / (1024 * 1024);\n+\t\t\ttx_er_shaper.max_burst_size =\n+\t\t\t\tnode->profile->params.peak.size;\n+\t\t\ttx_er_shaper.rate_limit =\n+\t\t\t\tnode->profile->params.peak.rate / (1024 * 1024);\n+\t\t\tret = dpni_set_tx_shaping(dpni, 0, priv->token,\n+\t\t\t\t\t&tx_cr_shaper, &tx_er_shaper, 0);\n+\t\t\tif (ret) {\n+\t\t\t\tret = -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_SHAPER_PROFILE, NULL,\n+\t\t\t\t\t\"Error in setting Shaping\\n\");\n+\t\t\t\tgoto out;\n+\t\t\t}\n+\n+\t\t\tcontinue;\n+\t\t} else { /* level 1, all leaf nodes */\n+\t\t\tif (node->id >= dev->data->nb_tx_queues) {\n+\t\t\t\tret = -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t\tRTE_TM_ERROR_TYPE_NODE_ID, NULL,\n+\t\t\t\t\t\t\"Not enough txqs configured\\n\");\n+\t\t\t\tgoto out;\n+\t\t\t}\n+\n+\t\t\tif (conf[node->id])\n+\t\t\t\tcontinue;\n+\n+\t\t\tLIST_FOREACH(temp_node, &priv->nodes, next) {\n+\t\t\t\tif (temp_node->id == node->id ||\n+\t\t\t\t\ttemp_node->type == 0)\n+\t\t\t\t\tcontinue;\n+\t\t\t\tif (conf[temp_node->id])\n+\t\t\t\t\tcontinue;\n+\t\t\t\tif (node->priority == temp_node->priority) {\n+\t\t\t\t\tif (wfq_grp == 0) {\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_node->id].mode =\n+\t\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_A;\n+\t\t\t\t\t\t/* DPDK support lowest weight 1\n+\t\t\t\t\t\t * and DPAA2 platform 100\n+\t\t\t\t\t\t */\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_node->id].delta_bandwidth =\n+\t\t\t\t\t\t\t\ttemp_node->weight + 99;\n+\t\t\t\t\t} else if (wfq_grp == 1) {\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_node->id].mode =\n+\t\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_B;\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_node->id].delta_bandwidth =\n+\t\t\t\t\t\t\t\ttemp_node->weight + 99;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t/*TODO: add one more check for\n+\t\t\t\t\t\t * number of nodes in a group\n+\t\t\t\t\t\t */\n+\t\t\t\t\t\tret = -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\t\t\"Only 2 WFQ Groups are supported\\n\");\n+\t\t\t\t\t\tgoto out;\n+\t\t\t\t\t}\n+\t\t\t\t\tconf[temp_node->id] = 1;\n+\t\t\t\t\tis_wfq_grp = 1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (is_wfq_grp) {\n+\t\t\t\tif (wfq_grp == 0) {\n+\t\t\t\t\tprio_cfg.tc_sched[node->id].mode =\n+\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_A;\n+\t\t\t\t\tprio_cfg.tc_sched[node->id].delta_bandwidth =\n+\t\t\t\t\t\t\tnode->weight + 99;\n+\t\t\t\t\tprio_cfg.prio_group_A = node->priority;\n+\t\t\t\t} else if (wfq_grp == 1) {\n+\t\t\t\t\tprio_cfg.tc_sched[node->id].mode =\n+\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_B;\n+\t\t\t\t\tprio_cfg.tc_sched[node->id].delta_bandwidth =\n+\t\t\t\t\t\t\tnode->weight + 99;\n+\t\t\t\t\tprio_cfg.prio_group_B = node->priority;\n+\t\t\t\t}\n+\t\t\t\twfq_grp++;\n+\t\t\t\tis_wfq_grp = 0;\n+\t\t\t}\n+\t\t\tconf[node->id] = 1;\n+\t\t}\n+\t\tif (wfq_grp)\n+\t\t\tprio_cfg.separate_groups = 1;\n+\t}\n+\tret = dpni_set_tx_priorities(dpni, 0, priv->token, &prio_cfg);\n+\tif (ret) {\n+\t\tret = -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\"Scheduling Failed\\n\");\n+\t\tgoto out;\n+\t}\n+\n+\treturn 0;\n+\n+out:\n+\tif (clear_on_fail) {\n+\t\tdpaa2_tm_deinit(dev);\n+\t\tdpaa2_tm_init(dev);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+const struct rte_tm_ops dpaa2_tm_ops = {\n+\t.node_type_get = dpaa2_node_type_get,\n+\t.capabilities_get = dpaa2_capabilities_get,\n+\t.level_capabilities_get = dpaa2_level_capabilities_get,\n+\t.node_capabilities_get = dpaa2_node_capabilities_get,\n+\t.shaper_profile_add = dpaa2_shaper_profile_add,\n+\t.shaper_profile_delete = dpaa2_shaper_profile_delete,\n+\t.node_add = dpaa2_node_add,\n+\t.node_delete = dpaa2_node_delete,\n+\t.hierarchy_commit = dpaa2_hierarchy_commit,\n+};\ndiff --git a/drivers/net/dpaa2/dpaa2_tm.h b/drivers/net/dpaa2/dpaa2_tm.h\nnew file mode 100644\nindex 0000000000..6632fab687\n--- /dev/null\n+++ b/drivers/net/dpaa2/dpaa2_tm.h\n@@ -0,0 +1,32 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2020 NXP\n+ */\n+\n+#ifndef _DPAA2_TM_H_\n+#define _DPAA2_TM_H_\n+\n+#include <rte_tm.h>\n+\n+struct dpaa2_tm_shaper_profile {\n+\tLIST_ENTRY(dpaa2_tm_shaper_profile) next;\n+\tuint32_t id;\n+\tint refcnt;\n+\tstruct rte_tm_shaper_params params;\n+};\n+\n+struct dpaa2_tm_node {\n+\tLIST_ENTRY(dpaa2_tm_node) next;\n+\tuint32_t id;\n+\tuint32_t type;\n+\tint refcnt;\n+\tstruct dpaa2_tm_node *parent;\n+\tstruct dpaa2_tm_shaper_profile *profile;\n+\tuint32_t weight;\n+\tuint32_t priority;\n+\tuint64_t stats_mask;\n+};\n+\n+int dpaa2_tm_init(struct rte_eth_dev *dev);\n+void dpaa2_tm_deinit(struct rte_eth_dev *dev);\n+\n+#endif /* _DPAA2_TM_H_ */\ndiff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c\nindex 683d7bcc17..b254931386 100644\n--- a/drivers/net/dpaa2/mc/dpni.c\n+++ b/drivers/net/dpaa2/mc/dpni.c\n@@ -1,7 +1,7 @@\n /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)\n  *\n  * Copyright 2013-2016 Freescale Semiconductor Inc.\n- * Copyright 2016-2019 NXP\n+ * Copyright 2016-2020 NXP\n  *\n  */\n #include <fsl_mc_sys.h>\n@@ -949,6 +949,46 @@ int dpni_get_link_state(struct fsl_mc_io *mc_io,\n \treturn 0;\n }\n \n+/**\n+ * dpni_set_tx_shaping() - Set the transmit shaping\n+ * @mc_io:\t\tPointer to MC portal's I/O object\n+ * @cmd_flags:\t\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\t\tToken of DPNI object\n+ * @tx_cr_shaper:\tTX committed rate shaping configuration\n+ * @tx_er_shaper:\tTX excess rate shaping configuration\n+ * @coupled:\t\tCommitted and excess rate shapers are coupled\n+ *\n+ * Return:\t'0' on Success; Error code otherwise.\n+ */\n+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tconst struct dpni_tx_shaping_cfg *tx_cr_shaper,\n+\t\t\tconst struct dpni_tx_shaping_cfg *tx_er_shaper,\n+\t\t\tint coupled)\n+{\n+\tstruct dpni_cmd_set_tx_shaping *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;\n+\tcmd_params->tx_cr_max_burst_size =\n+\t\tcpu_to_le16(tx_cr_shaper->max_burst_size);\n+\tcmd_params->tx_er_max_burst_size =\n+\t\tcpu_to_le16(tx_er_shaper->max_burst_size);\n+\tcmd_params->tx_cr_rate_limit =\n+\t\tcpu_to_le32(tx_cr_shaper->rate_limit);\n+\tcmd_params->tx_er_rate_limit =\n+\t\tcpu_to_le32(tx_er_shaper->rate_limit);\n+\tdpni_set_field(cmd_params->coupled, COUPLED, coupled);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n /**\n  * dpni_set_max_frame_length() - Set the maximum received frame length.\n  * @mc_io:\t\tPointer to MC portal's I/O object\n@@ -1476,6 +1516,55 @@ int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io,\n \treturn mc_send_command(mc_io, &cmd);\n }\n \n+/**\n+ * dpni_set_tx_priorities() - Set transmission TC priority configuration\n+ * @mc_io:\tPointer to MC portal's I/O object\n+ * @cmd_flags:\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\tToken of DPNI object\n+ * @cfg:\tTransmission selection configuration\n+ *\n+ * warning:\tAllowed only when DPNI is disabled\n+ *\n+ * Return:\t'0' on Success; Error code otherwise.\n+ */\n+int dpni_set_tx_priorities(struct fsl_mc_io *mc_io,\n+\t\t\t   uint32_t cmd_flags,\n+\t\t\t   uint16_t token,\n+\t\t\t   const struct dpni_tx_priorities_cfg *cfg)\n+{\n+\tstruct dpni_cmd_set_tx_priorities *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\tint i;\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_PRIORITIES,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_set_tx_priorities *)cmd.params;\n+\tdpni_set_field(cmd_params->flags,\n+\t\t\t\tSEPARATE_GRP,\n+\t\t\t\tcfg->separate_groups);\n+\tcmd_params->prio_group_A = cfg->prio_group_A;\n+\tcmd_params->prio_group_B = cfg->prio_group_B;\n+\n+\tfor (i = 0; i + 1 < DPNI_MAX_TC; i = i + 2) {\n+\t\tdpni_set_field(cmd_params->modes[i / 2],\n+\t\t\t       MODE_1,\n+\t\t\t       cfg->tc_sched[i].mode);\n+\t\tdpni_set_field(cmd_params->modes[i / 2],\n+\t\t\t\t   MODE_2,\n+\t\t\t\t   cfg->tc_sched[i + 1].mode);\n+\t}\n+\n+\tfor (i = 0; i < DPNI_MAX_TC; i++) {\n+\t\tcmd_params->delta_bandwidth[i] =\n+\t\t\t\tcpu_to_le16(cfg->tc_sched[i].delta_bandwidth);\n+\t}\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n /**\n  * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration\n  * @mc_io:\tPointer to MC portal's I/O object\n@@ -1808,6 +1897,228 @@ int dpni_clear_fs_entries(struct fsl_mc_io *mc_io,\n \treturn mc_send_command(mc_io, &cmd);\n }\n \n+/**\n+ * dpni_set_rx_tc_policing() - Set Rx traffic class policing configuration\n+ * @mc_io:\tPointer to MC portal's I/O object\n+ * @cmd_flags:\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\tToken of DPNI object\n+ * @tc_id:\tTraffic class selection (0-7)\n+ * @cfg:\tTraffic class policing configuration\n+ *\n+ * Return:\t'0' on Success; error code otherwise.\n+ */\n+int dpni_set_rx_tc_policing(struct fsl_mc_io *mc_io,\n+\t\t\t    uint32_t cmd_flags,\n+\t\t\t    uint16_t token,\n+\t\t\t    uint8_t tc_id,\n+\t\t\t    const struct dpni_rx_tc_policing_cfg *cfg)\n+{\n+\tstruct dpni_cmd_set_rx_tc_policing *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_POLICING,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_set_rx_tc_policing *)cmd.params;\n+\tdpni_set_field(cmd_params->mode_color, COLOR, cfg->default_color);\n+\tdpni_set_field(cmd_params->mode_color, MODE, cfg->mode);\n+\tdpni_set_field(cmd_params->units, UNITS, cfg->units);\n+\tcmd_params->options = cpu_to_le32(cfg->options);\n+\tcmd_params->cir = cpu_to_le32(cfg->cir);\n+\tcmd_params->cbs = cpu_to_le32(cfg->cbs);\n+\tcmd_params->eir = cpu_to_le32(cfg->eir);\n+\tcmd_params->ebs = cpu_to_le32(cfg->ebs);\n+\tcmd_params->tc_id = tc_id;\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n+/**\n+ * dpni_get_rx_tc_policing() - Get Rx traffic class policing configuration\n+ * @mc_io:\tPointer to MC portal's I/O object\n+ * @cmd_flags:\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\tToken of DPNI object\n+ * @tc_id:\tTraffic class selection (0-7)\n+ * @cfg:\tTraffic class policing configuration\n+ *\n+ * Return:\t'0' on Success; error code otherwise.\n+ */\n+int dpni_get_rx_tc_policing(struct fsl_mc_io *mc_io,\n+\t\t\t    uint32_t cmd_flags,\n+\t\t\t    uint16_t token,\n+\t\t\t    uint8_t tc_id,\n+\t\t\t    struct dpni_rx_tc_policing_cfg *cfg)\n+{\n+\tstruct dpni_rsp_get_rx_tc_policing *rsp_params;\n+\tstruct dpni_cmd_get_rx_tc_policing *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\tint err;\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_TC_POLICING,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_get_rx_tc_policing *)cmd.params;\n+\tcmd_params->tc_id = tc_id;\n+\n+\n+\t/* send command to mc*/\n+\terr =  mc_send_command(mc_io, &cmd);\n+\tif (err)\n+\t\treturn err;\n+\n+\trsp_params =  (struct dpni_rsp_get_rx_tc_policing *)cmd.params;\n+\tcfg->options = le32_to_cpu(rsp_params->options);\n+\tcfg->cir = le32_to_cpu(rsp_params->cir);\n+\tcfg->cbs = le32_to_cpu(rsp_params->cbs);\n+\tcfg->eir = le32_to_cpu(rsp_params->eir);\n+\tcfg->ebs = le32_to_cpu(rsp_params->ebs);\n+\tcfg->units = dpni_get_field(rsp_params->units, UNITS);\n+\tcfg->mode = dpni_get_field(rsp_params->mode_color, MODE);\n+\tcfg->default_color = dpni_get_field(rsp_params->mode_color, COLOR);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dpni_prepare_early_drop() - prepare an early drop.\n+ * @cfg:\t\tEarly-drop configuration\n+ * @early_drop_buf:\tZeroed 256 bytes of memory before mapping it to DMA\n+ *\n+ * This function has to be called before dpni_set_rx_tc_early_drop or\n+ * dpni_set_tx_tc_early_drop\n+ *\n+ */\n+void dpni_prepare_early_drop(const struct dpni_early_drop_cfg *cfg,\n+\t\t\t     uint8_t *early_drop_buf)\n+{\n+\tstruct dpni_early_drop *ext_params;\n+\n+\text_params = (struct dpni_early_drop *)early_drop_buf;\n+\n+\tdpni_set_field(ext_params->flags, DROP_ENABLE, cfg->enable);\n+\tdpni_set_field(ext_params->flags, DROP_UNITS, cfg->units);\n+\text_params->green_drop_probability = cfg->green.drop_probability;\n+\text_params->green_max_threshold = cpu_to_le64(cfg->green.max_threshold);\n+\text_params->green_min_threshold = cpu_to_le64(cfg->green.min_threshold);\n+\text_params->yellow_drop_probability = cfg->yellow.drop_probability;\n+\text_params->yellow_max_threshold =\n+\t\tcpu_to_le64(cfg->yellow.max_threshold);\n+\text_params->yellow_min_threshold =\n+\t\tcpu_to_le64(cfg->yellow.min_threshold);\n+\text_params->red_drop_probability = cfg->red.drop_probability;\n+\text_params->red_max_threshold = cpu_to_le64(cfg->red.max_threshold);\n+\text_params->red_min_threshold = cpu_to_le64(cfg->red.min_threshold);\n+}\n+\n+/**\n+ * dpni_extract_early_drop() - extract the early drop configuration.\n+ * @cfg:\t\tEarly-drop configuration\n+ * @early_drop_buf:\tZeroed 256 bytes of memory before mapping it to DMA\n+ *\n+ * This function has to be called after dpni_get_rx_tc_early_drop or\n+ * dpni_get_tx_tc_early_drop\n+ *\n+ */\n+void dpni_extract_early_drop(struct dpni_early_drop_cfg *cfg,\n+\t\t\t     const uint8_t *early_drop_buf)\n+{\n+\tconst struct dpni_early_drop *ext_params;\n+\n+\text_params = (const struct dpni_early_drop *)early_drop_buf;\n+\n+\tcfg->enable = dpni_get_field(ext_params->flags, DROP_ENABLE);\n+\tcfg->units = dpni_get_field(ext_params->flags, DROP_UNITS);\n+\tcfg->green.drop_probability = ext_params->green_drop_probability;\n+\tcfg->green.max_threshold = le64_to_cpu(ext_params->green_max_threshold);\n+\tcfg->green.min_threshold = le64_to_cpu(ext_params->green_min_threshold);\n+\tcfg->yellow.drop_probability = ext_params->yellow_drop_probability;\n+\tcfg->yellow.max_threshold =\n+\t\tle64_to_cpu(ext_params->yellow_max_threshold);\n+\tcfg->yellow.min_threshold =\n+\t\tle64_to_cpu(ext_params->yellow_min_threshold);\n+\tcfg->red.drop_probability = ext_params->red_drop_probability;\n+\tcfg->red.max_threshold = le64_to_cpu(ext_params->red_max_threshold);\n+\tcfg->red.min_threshold = le64_to_cpu(ext_params->red_min_threshold);\n+}\n+\n+/**\n+ * dpni_set_early_drop() - Set traffic class early-drop configuration\n+ * @mc_io:\tPointer to MC portal's I/O object\n+ * @cmd_flags:\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\tToken of DPNI object\n+ * @qtype:\tType of queue - only Rx and Tx types are supported\n+ * @tc_id:\tTraffic class selection (0-7)\n+ * @early_drop_iova:  I/O virtual address of 256 bytes DMA-able memory filled\n+ *\twith the early-drop configuration by calling dpni_prepare_early_drop()\n+ *\n+ * warning: Before calling this function, call dpni_prepare_early_drop() to\n+ *\t\t\tprepare the early_drop_iova parameter\n+ *\n+ * Return:\t'0' on Success; error code otherwise.\n+ */\n+int dpni_set_early_drop(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tenum dpni_queue_type qtype,\n+\t\t\tuint8_t tc_id,\n+\t\t\tuint64_t early_drop_iova)\n+{\n+\tstruct dpni_cmd_early_drop *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_EARLY_DROP,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_early_drop *)cmd.params;\n+\tcmd_params->qtype = qtype;\n+\tcmd_params->tc = tc_id;\n+\tcmd_params->early_drop_iova = cpu_to_le64(early_drop_iova);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n+/**\n+ * dpni_get_early_drop() - Get Rx traffic class early-drop configuration\n+ * @mc_io:\tPointer to MC portal's I/O object\n+ * @cmd_flags:\tCommand flags; one or more of 'MC_CMD_FLAG_'\n+ * @token:\tToken of DPNI object\n+ * @qtype:\tType of queue - only Rx and Tx types are supported\n+ * @tc_id:\tTraffic class selection (0-7)\n+ * @early_drop_iova:  I/O virtual address of 256 bytes DMA-able memory\n+ *\n+ * warning: After calling this function, call dpni_extract_early_drop() to\n+ *\tget the early drop configuration\n+ *\n+ * Return:\t'0' on Success; error code otherwise.\n+ */\n+int dpni_get_early_drop(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tenum dpni_queue_type qtype,\n+\t\t\tuint8_t tc_id,\n+\t\t\tuint64_t early_drop_iova)\n+{\n+\tstruct dpni_cmd_early_drop *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_EARLY_DROP,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_cmd_early_drop *)cmd.params;\n+\tcmd_params->qtype = qtype;\n+\tcmd_params->tc = tc_id;\n+\tcmd_params->early_drop_iova = cpu_to_le64(early_drop_iova);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n /**\n  * dpni_set_congestion_notification() - Set traffic class congestion\n  *\tnotification configuration\ndiff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h\nindex 598911ddd1..df42746c9a 100644\n--- a/drivers/net/dpaa2/mc/fsl_dpni.h\n+++ b/drivers/net/dpaa2/mc/fsl_dpni.h\n@@ -1,7 +1,7 @@\n /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)\n  *\n  * Copyright 2013-2016 Freescale Semiconductor Inc.\n- * Copyright 2016-2019 NXP\n+ * Copyright 2016-2020 NXP\n  *\n  */\n #ifndef __FSL_DPNI_H\n@@ -731,6 +731,23 @@ int dpni_get_link_state(struct fsl_mc_io *mc_io,\n \t\t\tuint16_t token,\n \t\t\tstruct dpni_link_state *state);\n \n+/**\n+ * struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration\n+ * @rate_limit:\t\tRate in Mbps\n+ * @max_burst_size:\tBurst size in bytes (up to 64KB)\n+ */\n+struct dpni_tx_shaping_cfg {\n+\tuint32_t rate_limit;\n+\tuint16_t max_burst_size;\n+};\n+\n+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tconst struct dpni_tx_shaping_cfg *tx_cr_shaper,\n+\t\t\tconst struct dpni_tx_shaping_cfg *tx_er_shaper,\n+\t\t\tint coupled);\n+\n int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,\n \t\t\t      uint32_t cmd_flags,\n \t\t\t      uint16_t token,\n@@ -832,6 +849,49 @@ int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io,\n \t\t\t    uint32_t cmd_flags,\n \t\t\t    uint16_t token);\n \n+/**\n+ * enum dpni_tx_schedule_mode - DPNI Tx scheduling mode\n+ * @DPNI_TX_SCHED_STRICT_PRIORITY: strict priority\n+ * @DPNI_TX_SCHED_WEIGHTED_A: weighted based scheduling in group A\n+ * @DPNI_TX_SCHED_WEIGHTED_B: weighted based scheduling in group B\n+ */\n+enum dpni_tx_schedule_mode {\n+\tDPNI_TX_SCHED_STRICT_PRIORITY = 0,\n+\tDPNI_TX_SCHED_WEIGHTED_A,\n+\tDPNI_TX_SCHED_WEIGHTED_B,\n+};\n+\n+/**\n+ * struct dpni_tx_schedule_cfg - Structure representing Tx scheduling conf\n+ * @mode:\t\tScheduling mode\n+ * @delta_bandwidth:\tBandwidth represented in weights from 100 to 10000;\n+ *\tnot applicable for 'strict-priority' mode;\n+ */\n+struct dpni_tx_schedule_cfg {\n+\tenum dpni_tx_schedule_mode\tmode;\n+\tuint16_t\t\t\tdelta_bandwidth;\n+};\n+\n+/**\n+ * struct dpni_tx_priorities_cfg - Structure representing transmission\n+ *\t\t\t\t\tpriorities for DPNI TCs\n+ * @tc_sched:\tAn array of traffic-classes\n+ * @prio_group_A: Priority of group A\n+ * @prio_group_B: Priority of group B\n+ * @separate_groups: Treat A and B groups as separate\n+ */\n+struct dpni_tx_priorities_cfg {\n+\tstruct dpni_tx_schedule_cfg tc_sched[DPNI_MAX_TC];\n+\tuint32_t prio_group_A;\n+\tuint32_t prio_group_B;\n+\tuint8_t separate_groups;\n+};\n+\n+int dpni_set_tx_priorities(struct fsl_mc_io\t\t\t*mc_io,\n+\t\t\t   uint32_t\t\t\t\tcmd_flags,\n+\t\t\t   uint16_t\t\t\t\ttoken,\n+\t\t\t   const struct dpni_tx_priorities_cfg\t*cfg);\n+\n /**\n  * enum dpni_dist_mode - DPNI distribution mode\n  * @DPNI_DIST_MODE_NONE: No distribution\n@@ -904,6 +964,90 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,\n \t\t\tuint8_t tc_id,\n \t\t\tconst struct dpni_rx_tc_dist_cfg *cfg);\n \n+/**\n+ * Set to select color aware mode (otherwise - color blind)\n+ */\n+#define DPNI_POLICER_OPT_COLOR_AWARE\t0x00000001\n+/**\n+ * Set to discard frame with RED color\n+ */\n+#define DPNI_POLICER_OPT_DISCARD_RED\t0x00000002\n+\n+/**\n+ * enum dpni_policer_mode - selecting the policer mode\n+ * @DPNI_POLICER_MODE_NONE: Policer is disabled\n+ * @DPNI_POLICER_MODE_PASS_THROUGH: Policer pass through\n+ * @DPNI_POLICER_MODE_RFC_2698: Policer algorithm RFC 2698\n+ * @DPNI_POLICER_MODE_RFC_4115: Policer algorithm RFC 4115\n+ */\n+enum dpni_policer_mode {\n+\tDPNI_POLICER_MODE_NONE = 0,\n+\tDPNI_POLICER_MODE_PASS_THROUGH,\n+\tDPNI_POLICER_MODE_RFC_2698,\n+\tDPNI_POLICER_MODE_RFC_4115\n+};\n+\n+/**\n+ * enum dpni_policer_unit - DPNI policer units\n+ * @DPNI_POLICER_UNIT_BYTES: bytes units\n+ * @DPNI_POLICER_UNIT_FRAMES: frames units\n+ */\n+enum dpni_policer_unit {\n+\tDPNI_POLICER_UNIT_BYTES = 0,\n+\tDPNI_POLICER_UNIT_FRAMES\n+};\n+\n+/**\n+ * enum dpni_policer_color - selecting the policer color\n+ * @DPNI_POLICER_COLOR_GREEN: Green color\n+ * @DPNI_POLICER_COLOR_YELLOW: Yellow color\n+ * @DPNI_POLICER_COLOR_RED: Red color\n+ */\n+enum dpni_policer_color {\n+\tDPNI_POLICER_COLOR_GREEN = 0,\n+\tDPNI_POLICER_COLOR_YELLOW,\n+\tDPNI_POLICER_COLOR_RED\n+};\n+\n+/**\n+ * struct dpni_rx_tc_policing_cfg - Policer configuration\n+ * @options: Mask of available options; use 'DPNI_POLICER_OPT_<X>' values\n+ * @mode: policer mode\n+ * @default_color: For pass-through mode the policer re-colors with this\n+ *\tcolor any incoming packets. For Color aware non-pass-through mode:\n+ *\tpolicer re-colors with this color all packets with FD[DROPP]>2.\n+ * @units: Bytes or Packets\n+ * @cir: Committed information rate (CIR) in Kbps or packets/second\n+ * @cbs: Committed burst size (CBS) in bytes or packets\n+ * @eir: Peak information rate (PIR, rfc2698) in Kbps or packets/second\n+ *\t Excess information rate (EIR, rfc4115) in Kbps or packets/second\n+ * @ebs: Peak burst size (PBS, rfc2698) in bytes or packets\n+ *       Excess burst size (EBS, rfc4115) in bytes or packets\n+ */\n+struct dpni_rx_tc_policing_cfg {\n+\tuint32_t options;\n+\tenum dpni_policer_mode mode;\n+\tenum dpni_policer_unit units;\n+\tenum dpni_policer_color default_color;\n+\tuint32_t cir;\n+\tuint32_t cbs;\n+\tuint32_t eir;\n+\tuint32_t ebs;\n+};\n+\n+\n+int dpni_set_rx_tc_policing(struct fsl_mc_io *mc_io,\n+\t\t\t    uint32_t cmd_flags,\n+\t\t\t    uint16_t token,\n+\t\t\t    uint8_t tc_id,\n+\t\t\t    const struct dpni_rx_tc_policing_cfg *cfg);\n+\n+int dpni_get_rx_tc_policing(struct fsl_mc_io *mc_io,\n+\t\t\t    uint32_t cmd_flags,\n+\t\t\t    uint16_t token,\n+\t\t\t    uint8_t tc_id,\n+\t\t\t    struct dpni_rx_tc_policing_cfg *cfg);\n+\n /**\n  * enum dpni_congestion_unit - DPNI congestion units\n  * @DPNI_CONGESTION_UNIT_BYTES: bytes units\n@@ -914,6 +1058,70 @@ enum dpni_congestion_unit {\n \tDPNI_CONGESTION_UNIT_FRAMES\n };\n \n+/**\n+ * enum dpni_early_drop_mode - DPNI early drop mode\n+ * @DPNI_EARLY_DROP_MODE_NONE: early drop is disabled\n+ * @DPNI_EARLY_DROP_MODE_TAIL: early drop in taildrop mode\n+ * @DPNI_EARLY_DROP_MODE_WRED: early drop in WRED mode\n+ */\n+enum dpni_early_drop_mode {\n+\tDPNI_EARLY_DROP_MODE_NONE = 0,\n+\tDPNI_EARLY_DROP_MODE_TAIL,\n+\tDPNI_EARLY_DROP_MODE_WRED\n+};\n+\n+/**\n+ * struct dpni_wred_cfg - WRED configuration\n+ * @max_threshold: maximum threshold that packets may be discarded. Above this\n+ *\t  threshold all packets are discarded; must be less than 2^39;\n+ *\t  approximated to be expressed as (x+256)*2^(y-1) due to HW\n+ *\t  implementation.\n+ * @min_threshold: minimum threshold that packets may be discarded at\n+ * @drop_probability: probability that a packet will be discarded (1-100,\n+ *\t\t\tassociated with the max_threshold).\n+ */\n+struct dpni_wred_cfg {\n+\tuint64_t max_threshold;\n+\tuint64_t min_threshold;\n+\tuint8_t drop_probability;\n+};\n+\n+/**\n+ * struct dpni_early_drop_cfg - early-drop configuration\n+ * @enable: drop enable\n+ * @units: units type\n+ * @green: WRED - 'green' configuration\n+ * @yellow: WRED - 'yellow' configuration\n+ * @red: WRED - 'red' configuration\n+ */\n+struct dpni_early_drop_cfg {\n+\tuint8_t enable;\n+\tenum dpni_congestion_unit units;\n+\tstruct dpni_wred_cfg green;\n+\tstruct dpni_wred_cfg yellow;\n+\tstruct dpni_wred_cfg red;\n+};\n+\n+void dpni_prepare_early_drop(const struct dpni_early_drop_cfg *cfg,\n+\t\t\t     uint8_t *early_drop_buf);\n+\n+void dpni_extract_early_drop(struct dpni_early_drop_cfg *cfg,\n+\t\t\t     const uint8_t *early_drop_buf);\n+\n+int dpni_set_early_drop(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tenum dpni_queue_type qtype,\n+\t\t\tuint8_t tc_id,\n+\t\t\tuint64_t early_drop_iova);\n+\n+int dpni_get_early_drop(struct fsl_mc_io *mc_io,\n+\t\t\tuint32_t cmd_flags,\n+\t\t\tuint16_t token,\n+\t\t\tenum dpni_queue_type qtype,\n+\t\t\tuint8_t tc_id,\n+\t\t\tuint64_t early_drop_iova);\n+\n /**\n  * enum dpni_dest - DPNI destination types\n  * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and\ndiff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\nindex 9e7376200d..c40090b8fe 100644\n--- a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\n+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\n@@ -1,7 +1,7 @@\n /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)\n  *\n  * Copyright 2013-2016 Freescale Semiconductor Inc.\n- * Copyright 2016-2019 NXP\n+ * Copyright 2016-2020 NXP\n  *\n  */\n #ifndef _FSL_DPNI_CMD_H\n@@ -69,6 +69,8 @@\n \n #define DPNI_CMDID_SET_RX_TC_DIST\t\tDPNI_CMD_V3(0x235)\n \n+#define DPNI_CMDID_SET_RX_TC_POLICING\t\tDPNI_CMD(0x23E)\n+\n #define DPNI_CMDID_SET_QOS_TBL\t\t\tDPNI_CMD_V2(0x240)\n #define DPNI_CMDID_ADD_QOS_ENT\t\t\tDPNI_CMD_V2(0x241)\n #define DPNI_CMDID_REMOVE_QOS_ENT\t\tDPNI_CMD(0x242)\n@@ -77,6 +79,9 @@\n #define DPNI_CMDID_REMOVE_FS_ENT\t\tDPNI_CMD(0x245)\n #define DPNI_CMDID_CLR_FS_ENT\t\t\tDPNI_CMD(0x246)\n \n+#define DPNI_CMDID_SET_TX_PRIORITIES\t\tDPNI_CMD_V2(0x250)\n+#define DPNI_CMDID_GET_RX_TC_POLICING\t\tDPNI_CMD(0x251)\n+\n #define DPNI_CMDID_GET_STATISTICS\t\tDPNI_CMD_V3(0x25D)\n #define DPNI_CMDID_RESET_STATISTICS\t\tDPNI_CMD(0x25E)\n #define DPNI_CMDID_GET_QUEUE\t\t\tDPNI_CMD_V2(0x25F)\n@@ -354,6 +359,19 @@ struct dpni_rsp_get_link_state {\n \tuint64_t advertising;\n };\n \n+#define DPNI_COUPLED_SHIFT\t0\n+#define DPNI_COUPLED_SIZE\t1\n+\n+struct dpni_cmd_set_tx_shaping {\n+\tuint16_t tx_cr_max_burst_size;\n+\tuint16_t tx_er_max_burst_size;\n+\tuint32_t pad;\n+\tuint32_t tx_cr_rate_limit;\n+\tuint32_t tx_er_rate_limit;\n+\t/* from LSB: coupled:1 */\n+\tuint8_t coupled;\n+};\n+\n struct dpni_cmd_set_max_frame_length {\n \tuint16_t max_frame_length;\n };\n@@ -592,6 +610,45 @@ struct dpni_cmd_clear_fs_entries {\n \tuint8_t tc_id;\n };\n \n+#define DPNI_MODE_SHIFT\t\t0\n+#define DPNI_MODE_SIZE\t\t4\n+#define DPNI_COLOR_SHIFT\t4\n+#define DPNI_COLOR_SIZE\t\t4\n+#define DPNI_UNITS_SHIFT\t0\n+#define DPNI_UNITS_SIZE\t\t4\n+\n+struct dpni_cmd_set_rx_tc_policing {\n+\t/* from LSB: mode:4 color:4 */\n+\tuint8_t mode_color;\n+\t/* from LSB: units: 4 */\n+\tuint8_t units;\n+\tuint8_t tc_id;\n+\tuint8_t pad;\n+\tuint32_t options;\n+\tuint32_t cir;\n+\tuint32_t cbs;\n+\tuint32_t eir;\n+\tuint32_t ebs;\n+};\n+\n+struct dpni_cmd_get_rx_tc_policing {\n+\tuint16_t pad;\n+\tuint8_t tc_id;\n+};\n+\n+struct dpni_rsp_get_rx_tc_policing {\n+\t/* from LSB: mode:4 color:4 */\n+\tuint8_t mode_color;\n+\t/* from LSB: units: 4 */\n+\tuint8_t units;\n+\tuint16_t pad;\n+\tuint32_t options;\n+\tuint32_t cir;\n+\tuint32_t cbs;\n+\tuint32_t eir;\n+\tuint32_t ebs;\n+};\n+\n #define DPNI_DROP_ENABLE_SHIFT\t0\n #define DPNI_DROP_ENABLE_SIZE\t1\n #define DPNI_DROP_UNITS_SHIFT\t2\ndiff --git a/drivers/net/dpaa2/meson.build b/drivers/net/dpaa2/meson.build\nindex 844dd25159..f5f411d592 100644\n--- a/drivers/net/dpaa2/meson.build\n+++ b/drivers/net/dpaa2/meson.build\n@@ -1,5 +1,5 @@\n # SPDX-License-Identifier: BSD-3-Clause\n-# Copyright 2018 NXP\n+# Copyright 2018-2021 NXP\n \n if not is_linux\n \tbuild = false\n@@ -8,6 +8,7 @@ endif\n \n deps += ['mempool_dpaa2']\n sources = files('base/dpaa2_hw_dpni.c',\n+\t\t'dpaa2_tm.c',\n \t\t'dpaa2_mux.c',\n \t\t'dpaa2_ethdev.c',\n \t\t'dpaa2_flow.c',\n",
    "prefixes": [
        "v3",
        "08/23"
    ]
}