get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 104935,
    "url": "http://patchwork.dpdk.org/api/patches/104935/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20211206121824.3493-8-nipun.gupta@nxp.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20211206121824.3493-8-nipun.gupta@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211206121824.3493-8-nipun.gupta@nxp.com",
    "date": "2021-12-06T12:18:14",
    "name": "[07/17] net/dpaa2: add support for level 2 in traffic management",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "546e5b3bdc00feb5380ba7c79cc64ffad24488b3",
    "submitter": {
        "id": 471,
        "url": "http://patchwork.dpdk.org/api/people/471/?format=api",
        "name": "Nipun Gupta",
        "email": "nipun.gupta@nxp.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20211206121824.3493-8-nipun.gupta@nxp.com/mbox/",
    "series": [
        {
            "id": 20873,
            "url": "http://patchwork.dpdk.org/api/series/20873/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=20873",
            "date": "2021-12-06T12:18:07",
            "name": "features and fixes on NXP eth devices",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/20873/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/104935/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/104935/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 91FA4A034F;\n\tMon,  6 Dec 2021 13:19:13 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 293AA4273E;\n\tMon,  6 Dec 2021 13:18:38 +0100 (CET)",
            "from inva020.nxp.com (inva020.nxp.com [92.121.34.13])\n by mails.dpdk.org (Postfix) with ESMTP id 63FF641186\n for <dev@dpdk.org>; Mon,  6 Dec 2021 13:18:30 +0100 (CET)",
            "from inva020.nxp.com (localhost [127.0.0.1])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 3EB121A1329;\n Mon,  6 Dec 2021 13:18:30 +0100 (CET)",
            "from aprdc01srsp001v.ap-rdc01.nxp.com\n (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A546B1A1AE7;\n Mon,  6 Dec 2021 13:18:29 +0100 (CET)",
            "from lsv03274.swis.in-blr01.nxp.com (lsv03274.swis.in-blr01.nxp.com\n [92.120.147.114])\n by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 0E31B183AD6D;\n Mon,  6 Dec 2021 20:18:29 +0800 (+08)"
        ],
        "From": "nipun.gupta@nxp.com",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, ferruh.yigit@intel.com, hemant.agrawal@nxp.com,\n Gagandeep Singh <g.singh@nxp.com>",
        "Subject": "[PATCH 07/17] net/dpaa2: add support for level 2 in traffic\n management",
        "Date": "Mon,  6 Dec 2021 17:48:14 +0530",
        "Message-Id": "<20211206121824.3493-8-nipun.gupta@nxp.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20211206121824.3493-1-nipun.gupta@nxp.com>",
        "References": "<20211206121824.3493-1-nipun.gupta@nxp.com>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "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: Gagandeep Singh <g.singh@nxp.com>\n\nThis patch adds support for level 2 for QoS shaping.\n\nSigned-off-by: Gagandeep Singh <g.singh@nxp.com>\n---\n doc/guides/nics/dpaa2.rst           |   2 +-\n drivers/net/dpaa2/dpaa2_ethdev.c    |  55 ++-\n drivers/net/dpaa2/dpaa2_ethdev.h    |   6 +-\n drivers/net/dpaa2/dpaa2_tm.c        | 563 ++++++++++++++++++++++------\n drivers/net/dpaa2/dpaa2_tm.h        |  17 +-\n drivers/net/dpaa2/mc/dpni.c         | 302 +++++++++------\n drivers/net/dpaa2/mc/fsl_dpni.h     | 119 +++---\n drivers/net/dpaa2/mc/fsl_dpni_cmd.h |  79 ++--\n 8 files changed, 791 insertions(+), 352 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst\nindex 831bc56488..2d113f53df 100644\n--- a/doc/guides/nics/dpaa2.rst\n+++ b/doc/guides/nics/dpaa2.rst\n@@ -588,7 +588,7 @@ Supported Features\n \n The following capabilities are supported:\n \n-- Level0 (root node) and Level1 are supported.\n+- Level0 (root node), Level1 and Level2 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.\ndiff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c\nindex 18ff07249f..b91e773605 100644\n--- a/drivers/net/dpaa2/dpaa2_ethdev.c\n+++ b/drivers/net/dpaa2/dpaa2_ethdev.c\n@@ -852,6 +852,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \tstruct dpni_queue tx_conf_cfg;\n \tstruct dpni_queue tx_flow_cfg;\n \tuint8_t options = 0, flow_id;\n+\tuint16_t channel_id;\n \tstruct dpni_queue_id qid;\n \tuint32_t tc_id;\n \tint ret;\n@@ -877,20 +878,6 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \tmemset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));\n \tmemset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));\n \n-\ttc_id = tx_queue_id;\n-\tflow_id = 0;\n-\n-\tret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,\n-\t\t\ttc_id, flow_id, options, &tx_flow_cfg);\n-\tif (ret) {\n-\t\tDPAA2_PMD_ERR(\"Error in setting the tx flow: \"\n-\t\t\t\"tc_id=%d, flow=%d err=%d\",\n-\t\t\ttc_id, flow_id, ret);\n-\t\t\treturn -1;\n-\t}\n-\n-\tdpaa2_q->flow_id = flow_id;\n-\n \tif (tx_queue_id == 0) {\n \t\t/*Set tx-conf and error configuration*/\n \t\tif (priv->flags & DPAA2_TX_CONF_ENABLE)\n@@ -907,10 +894,26 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t\t\treturn -1;\n \t\t}\n \t}\n+\n+\ttc_id = tx_queue_id % priv->num_tx_tc;\n+\tchannel_id = (uint8_t)(tx_queue_id / priv->num_tx_tc) % priv->num_channels;\n+\tflow_id = 0;\n+\n+\tret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,\n+\t\t\t((channel_id << 8) | tc_id), flow_id, options, &tx_flow_cfg);\n+\tif (ret) {\n+\t\tDPAA2_PMD_ERR(\"Error in setting the tx flow: \"\n+\t\t\t\"tc_id=%d, flow=%d err=%d\",\n+\t\t\ttc_id, flow_id, ret);\n+\t\t\treturn -1;\n+\t}\n+\n+\tdpaa2_q->flow_id = flow_id;\n+\n \tdpaa2_q->tc_index = tc_id;\n \n \tret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,\n-\t\t\t     DPNI_QUEUE_TX, dpaa2_q->tc_index,\n+\t\t\t     DPNI_QUEUE_TX, ((channel_id << 8) | dpaa2_q->tc_index),\n \t\t\t     dpaa2_q->flow_id, &tx_flow_cfg, &qid);\n \tif (ret) {\n \t\tDPAA2_PMD_ERR(\"Error in getting LFQID err=%d\", ret);\n@@ -942,7 +945,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t\tret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW,\n \t\t\t\t\t\t       priv->token,\n \t\t\t\t\t\t       DPNI_QUEUE_TX,\n-\t\t\t\t\t\t       tc_id,\n+\t\t\t\t\t\t       ((channel_id << 8) | tc_id),\n \t\t\t\t\t\t       &cong_notif_cfg);\n \t\tif (ret) {\n \t\t\tDPAA2_PMD_ERR(\n@@ -959,7 +962,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t\toptions = options | DPNI_QUEUE_OPT_USER_CTX;\n \t\ttx_conf_cfg.user_context = (size_t)(dpaa2_q);\n \t\tret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token,\n-\t\t\t     DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index,\n+\t\t\t     DPNI_QUEUE_TX_CONFIRM, ((channel_id << 8) | dpaa2_tx_conf_q->tc_index),\n \t\t\t     dpaa2_tx_conf_q->flow_id, options, &tx_conf_cfg);\n \t\tif (ret) {\n \t\t\tDPAA2_PMD_ERR(\"Error in setting the tx conf flow: \"\n@@ -970,7 +973,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t\t}\n \n \t\tret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,\n-\t\t\t     DPNI_QUEUE_TX_CONFIRM, dpaa2_tx_conf_q->tc_index,\n+\t\t\t     DPNI_QUEUE_TX_CONFIRM, ((channel_id << 8) | dpaa2_tx_conf_q->tc_index),\n \t\t\t     dpaa2_tx_conf_q->flow_id, &tx_conf_cfg, &qid);\n \t\tif (ret) {\n \t\t\tDPAA2_PMD_ERR(\"Error in getting LFQID err=%d\", ret);\n@@ -1152,7 +1155,6 @@ dpaa2_dev_start(struct rte_eth_dev *dev)\n \tstruct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;\n \tstruct dpni_queue cfg;\n \tstruct dpni_error_cfg\terr_cfg;\n-\tuint16_t qdid;\n \tstruct dpni_queue_id qid;\n \tstruct dpaa2_queue *dpaa2_q;\n \tint ret, i;\n@@ -1162,7 +1164,6 @@ dpaa2_dev_start(struct rte_eth_dev *dev)\n \tintr_handle = dpaa2_dev->intr_handle;\n \n \tPMD_INIT_FUNC_TRACE();\n-\n \tret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);\n \tif (ret) {\n \t\tDPAA2_PMD_ERR(\"Failure in enabling dpni %d device: err=%d\",\n@@ -1173,14 +1174,6 @@ dpaa2_dev_start(struct rte_eth_dev *dev)\n \t/* Power up the phy. Needed to make the link go UP */\n \tdpaa2_dev_set_link_up(dev);\n \n-\tret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token,\n-\t\t\t    DPNI_QUEUE_TX, &qdid);\n-\tif (ret) {\n-\t\tDPAA2_PMD_ERR(\"Error in getting qdid: err=%d\", ret);\n-\t\treturn ret;\n-\t}\n-\tpriv->qdid = qdid;\n-\n \tfor (i = 0; i < data->nb_rx_queues; i++) {\n \t\tdpaa2_q = (struct dpaa2_queue *)data->rx_queues[i];\n \t\tret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,\n@@ -2619,9 +2612,12 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)\n \t}\n \n \tpriv->num_rx_tc = attr.num_rx_tcs;\n+\tpriv->num_tx_tc = attr.num_tx_tcs;\n \tpriv->qos_entries = attr.qos_entries;\n \tpriv->fs_entries = attr.fs_entries;\n \tpriv->dist_queues = attr.num_queues;\n+\tpriv->num_channels = attr.num_channels;\n+\tpriv->channel_inuse = 0;\n \n \t/* only if the custom CG is enabled */\n \tif (attr.options & DPNI_OPT_CUSTOM_CG)\n@@ -2635,8 +2631,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)\n \tfor (i = 0; i < attr.num_rx_tcs; i++)\n \t\tpriv->nb_rx_queues += attr.num_queues;\n \n-\t/* Using number of TX queues as number of TX TCs */\n-\tpriv->nb_tx_queues = attr.num_tx_tcs;\n+\tpriv->nb_tx_queues = attr.num_tx_tcs * attr.num_channels;\n \n \tDPAA2_PMD_DEBUG(\"RX-TC= %d, rx_queues= %d, tx_queues=%d, max_cgs=%d\",\n \t\t\tpriv->num_rx_tc, priv->nb_rx_queues,\ndiff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h\nindex e001a7e49d..1fc2fc367e 100644\n--- a/drivers/net/dpaa2/dpaa2_ethdev.h\n+++ b/drivers/net/dpaa2/dpaa2_ethdev.h\n@@ -25,6 +25,7 @@\n #define MAX_RX_QUEUES\t\t128\n #define MAX_TX_QUEUES\t\t16\n #define MAX_DPNI\t\t8\n+#define DPAA2_MAX_CHANNELS\t16\n \n #define DPAA2_RX_DEFAULT_NBDESC 512\n \n@@ -160,15 +161,17 @@ struct dpaa2_dev_priv {\n \tvoid *rx_vq[MAX_RX_QUEUES];\n \tvoid *tx_vq[MAX_TX_QUEUES];\n \tstruct dpaa2_bp_list *bp_list; /**<Attached buffer pool list */\n-\tvoid *tx_conf_vq[MAX_TX_QUEUES];\n+\tvoid *tx_conf_vq[MAX_TX_QUEUES * DPAA2_MAX_CHANNELS];\n \tvoid *rx_err_vq;\n \tuint8_t flags; /*dpaa2 config flags */\n \tuint8_t max_mac_filters;\n \tuint8_t max_vlan_filters;\n \tuint8_t num_rx_tc;\n+\tuint8_t num_tx_tc;\n \tuint16_t qos_entries;\n \tuint16_t fs_entries;\n \tuint8_t dist_queues;\n+\tuint8_t num_channels;\n \tuint8_t en_ordered;\n \tuint8_t en_loose_ordered;\n \tuint8_t max_cgs;\n@@ -190,6 +193,7 @@ struct dpaa2_dev_priv {\n \n \tstruct rte_eth_dev *eth_dev; /**< Pointer back to holding ethdev */\n \n+\tuint8_t channel_inuse;\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;\ndiff --git a/drivers/net/dpaa2/dpaa2_tm.c b/drivers/net/dpaa2/dpaa2_tm.c\nindex f5faaedfb4..8fe5bfa013 100644\n--- a/drivers/net/dpaa2/dpaa2_tm.c\n+++ b/drivers/net/dpaa2/dpaa2_tm.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright 2020 NXP\n+ * Copyright 2020-2021 NXP\n  */\n \n #include <rte_ethdev.h>\n@@ -7,12 +7,16 @@\n #include <rte_tm_driver.h>\n \n #include \"dpaa2_ethdev.h\"\n+#include \"dpaa2_pmd_logs.h\"\n+#include <dpaa2_hw_dpio.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+#define DPAA2_PKT_ADJUST_LEN_MIN 0\n+#define DPAA2_PKT_ADJUST_LEN_MAX 0x7ff\n \n int\n dpaa2_tm_init(struct rte_eth_dev *dev)\n@@ -66,6 +70,8 @@ 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+\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@@ -73,27 +79,31 @@ dpaa2_capabilities_get(struct rte_eth_dev *dev,\n \n \tmemset(cap, 0, sizeof(*cap));\n \n-\t/* root node(port) + txqs number, assuming each TX\n+\t/* root node(port) + channels + 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->n_nodes_max = 1 + priv->num_channels + dev->data->nb_tx_queues;\n+\tcap->n_levels_max = MAX_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_n_max = 1 + priv->num_channels; /* LNI + channels */\n+\tcap->shaper_private_n_max = 1 + priv->num_channels;\n+\tcap->shaper_private_dual_rate_n_max = 1 + priv->num_channels;\n \tcap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;\n \tcap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;\n+\tcap->shaper_pkt_length_adjust_min = DPAA2_PKT_ADJUST_LEN_MIN;\n+\tcap->shaper_pkt_length_adjust_max = DPAA2_PKT_ADJUST_LEN_MAX;\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+\tif (priv->num_channels > DPNI_MAX_TC)\n+\t\tcap->sched_n_children_max = priv->num_channels;\n+\telse\n+\t\tcap->sched_n_children_max = DPNI_MAX_TC;\n \n-\tcap->dynamic_update_mask = RTE_TM_UPDATE_NODE_STATS;\n+\tcap->sched_sp_n_priorities_max = DPNI_MAX_TC;\n+\tcap->sched_wfq_n_children_per_group_max = DPNI_MAX_TC;\n+\tcap->sched_wfq_n_groups_max = 2;\n+\tcap->sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;\n \tcap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;\n \n \treturn 0;\n@@ -105,6 +115,8 @@ dpaa2_level_capabilities_get(struct rte_eth_dev *dev,\n \t\t\t    struct rte_tm_level_capabilities *cap,\n \t\t\t    struct rte_tm_error *error)\n {\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@@ -112,12 +124,12 @@ dpaa2_level_capabilities_get(struct rte_eth_dev *dev,\n \n \tmemset(cap, 0, sizeof(*cap));\n \n-\tif (level_id > 1)\n+\tif (level_id > QUEUE_LEVEL)\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+\tif (level_id == LNI_LEVEL) { /* Root node (LNI) */\n \t\tcap->n_nodes_max = 1;\n \t\tcap->n_nodes_nonleaf_max = 1;\n \t\tcap->non_leaf_nodes_identical = 1;\n@@ -127,20 +139,39 @@ dpaa2_level_capabilities_get(struct rte_eth_dev *dev,\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_n_children_max = priv->num_channels; /* no. of channels */\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.sched_wfq_n_children_per_group_max = 1;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 1;\n+\t\tcap->nonleaf.sched_wfq_weight_max = 1;\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 if (level_id == CHANNEL_LEVEL) { /* channels */\n+\t\tcap->n_nodes_max = priv->num_channels;\n+\t\tcap->n_nodes_nonleaf_max = priv->num_channels;\n+\t\tcap->n_nodes_leaf_max = 0;\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\t/* no. of class queues per channel */\n+\t\tcap->nonleaf.sched_n_children_max = priv->num_tx_tc;\n+\t\tcap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc;\n+\t\tcap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 2;\n+\t\tcap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;\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\t/* queues per channels * channel */\n+\t\tcap->n_nodes_max = priv->num_tx_tc * priv->num_channels;\n+\t\tcap->n_nodes_leaf_max = priv->num_tx_tc * priv->num_channels;\n \t\tcap->leaf_nodes_identical = 1;\n \n-\t\tcap->leaf.stats_mask = RTE_TM_STATS_N_PKTS;\n+\t\tcap->leaf.shaper_private_supported = 0;\n+\t\tcap->leaf.stats_mask = RTE_TM_STATS_N_PKTS |\n+\t\t\t\t       RTE_TM_STATS_N_BYTES;\n \t}\n \n \treturn 0;\n@@ -167,18 +198,33 @@ dpaa2_node_capabilities_get(struct rte_eth_dev *dev, uint32_t node_id,\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+\tif (node->level_id == LNI_LEVEL) {\n \t\tcap->shaper_private_supported = 1;\n+\t\tcap->shaper_private_dual_rate_supported = 1;\n+\t\tcap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;\n+\t\tcap->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_n_children_max = priv->num_channels;\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_children_per_group_max = 1;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 1;\n+\t\tcap->nonleaf.sched_wfq_weight_max = 1;\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS |\n+\t\t\t\t\t  RTE_TM_STATS_N_BYTES;\n+\t} else if (node->level_id == CHANNEL_LEVEL) {\n+\t\tcap->shaper_private_supported = 1;\n+\t\tcap->shaper_private_dual_rate_supported = 1;\n+\t\tcap->shaper_private_rate_min = DPAA2_SHAPER_MIN_RATE;\n+\t\tcap->shaper_private_rate_max = DPAA2_SHAPER_MAX_RATE;\n+\n+\t\tcap->nonleaf.sched_n_children_max = priv->num_tx_tc;\n+\t\tcap->nonleaf.sched_sp_n_priorities_max = priv->num_tx_tc;\n+\t\tcap->nonleaf.sched_wfq_n_children_per_group_max = priv->num_tx_tc;\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\tcap->nonleaf.sched_wfq_weight_max = DPAA2_WEIGHT_MAX / 100;\n \t} else {\n-\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS;\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS |\n+\t\t\t\t       RTE_TM_STATS_N_BYTES;\n \t}\n \n \treturn 0;\n@@ -202,7 +248,7 @@ dpaa2_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, int *is_leaf,\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+\t*is_leaf = node->type == LEAF_NODE ? 1 : 0;\n \n \treturn 0;\n }\n@@ -257,6 +303,13 @@ dpaa2_shaper_profile_add(struct rte_eth_dev *dev, uint32_t shaper_profile_id,\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+\tif (params->pkt_length_adjust > DPAA2_PKT_ADJUST_LEN_MAX ||\n+\t\t\tparams->pkt_length_adjust < DPAA2_PKT_ADJUST_LEN_MIN)\n+\t\treturn -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_TM_ERROR_TYPE_CAPABILITIES,\n+\t\t\t\t\t NULL,\n+\t\t\t\t\t \"Not supported pkt adjust length\\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@@ -318,7 +371,7 @@ dpaa2_node_check_params(struct rte_eth_dev *dev, uint32_t node_id,\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+\tif (level_id > QUEUE_LEVEL)\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@@ -338,39 +391,38 @@ dpaa2_node_check_params(struct rte_eth_dev *dev, uint32_t node_id,\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+\t/* verify non leaf nodes 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} else {\n+\t\tif (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE)\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\t\t\tRTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID,\n+\t\t\t\tNULL, \"Private shaper not supported on leaf\\n\");\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+\tif (level_id == QUEUE_LEVEL) {\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\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+\t} else if (level_id == LNI_LEVEL) {\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 \t}\n \n \treturn 0;\n@@ -407,7 +459,7 @@ dpaa2_node_add(struct rte_eth_dev *dev, uint32_t node_id,\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\tif (node->level_id != LNI_LEVEL)\n \t\t\t\tcontinue;\n \n \t\t\treturn -rte_tm_error_set(error, EINVAL,\n@@ -435,14 +487,29 @@ dpaa2_node_add(struct rte_eth_dev *dev, uint32_t node_id,\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 (node_id > dev->data->nb_tx_queues)\n+\t\tnode->type = NON_LEAF_NODE;\n+\telse\n+\t\tnode->type = LEAF_NODE;\n+\n+\tnode->level_id = level_id;\n+\tif (node->level_id == CHANNEL_LEVEL) {\n+\t\tif (priv->channel_inuse < priv->num_channels) {\n+\t\t\tnode->channel_id = priv->channel_inuse;\n+\t\t\tpriv->channel_inuse++;\n+\t\t} else {\n+\t\t\tprintf(\"error no channel id available\\n\");\n+\t\t}\n+\t}\n \n \tif (parent) {\n \t\tnode->parent = parent;\n \t\tparent->refcnt++;\n \t}\n \n+\t/* TODO: add check if refcnt is more than supported children */\n+\n \tif (profile) {\n \t\tnode->profile = profile;\n \t\tprofile->refcnt++;\n@@ -464,6 +531,7 @@ dpaa2_node_delete(struct rte_eth_dev *dev, uint32_t node_id,\n \tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n \tstruct dpaa2_tm_node *node;\n \n+\t/* XXX: update it */\n \tif (0) {\n \t\treturn -rte_tm_error_set(error, EPERM,\n \t\t\t\t\t RTE_TM_ERROR_TYPE_UNSPECIFIED,\n@@ -493,119 +561,326 @@ dpaa2_node_delete(struct rte_eth_dev *dev, uint32_t node_id,\n \treturn 0;\n }\n \n+static int\n+dpaa2_tm_configure_queue(struct rte_eth_dev *dev, struct dpaa2_tm_node *node)\n+{\n+\tint ret = 0;\n+\tuint32_t tc_id;\n+\tuint8_t flow_id, options = 0;\n+\tstruct dpni_queue tx_flow_cfg;\n+\tstruct dpni_queue_id qid;\n+\tstruct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_queue *dpaa2_q;\n+\n+\tmemset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));\n+\tdpaa2_q =  (struct dpaa2_queue *)dev->data->tx_queues[node->id];\n+\ttc_id = node->parent->tc_id;\n+\tnode->parent->tc_id++;\n+\tflow_id = 0;\n+\n+\tif (dpaa2_q == NULL) {\n+\t\tprintf(\"Queue is not configured for node = %d\\n\", node->id);\n+\t\treturn -1;\n+\t}\n+\n+\tDPAA2_PMD_DEBUG(\"tc_id = %d, channel = %d\\n\\n\", tc_id,\n+\t\t\tnode->parent->channel_id);\n+\tret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,\n+\t\t\t     ((node->parent->channel_id << 8) | tc_id),\n+\t\t\t     flow_id, options, &tx_flow_cfg);\n+\tif (ret) {\n+\t\tprintf(\"Error in setting the tx flow: \"\n+\t\t       \"channel id  = %d tc_id= %d, param = 0x%x \"\n+\t\t       \"flow=%d err=%d\\n\", node->parent->channel_id, tc_id,\n+\t\t       ((node->parent->channel_id << 8) | tc_id), flow_id,\n+\t\t       ret);\n+\t\treturn -1;\n+\t}\n+\n+\tdpaa2_q->flow_id = flow_id;\n+\tdpaa2_q->tc_index = tc_id;\n+\n+\tret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,\n+\t\tDPNI_QUEUE_TX, ((node->parent->channel_id << 8) | dpaa2_q->tc_index),\n+\t\tdpaa2_q->flow_id, &tx_flow_cfg, &qid);\n+\tif (ret) {\n+\t\tprintf(\"Error in getting LFQID err=%d\", ret);\n+\t\treturn -1;\n+\t}\n+\tdpaa2_q->fqid = qid.fqid;\n+\n+\t/* setting congestion notification */\n+\tif (!(priv->flags & DPAA2_TX_CGR_OFF)) {\n+\t\tstruct dpni_congestion_notification_cfg cong_notif_cfg = {0};\n+\n+\t\tcong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES;\n+\t\tcong_notif_cfg.threshold_entry = dpaa2_q->nb_desc;\n+\t\t/* Notify that the queue is not congested when the data in\n+\t\t * the queue is below this thershold.(90% of value)\n+\t\t */\n+\t\tcong_notif_cfg.threshold_exit = (dpaa2_q->nb_desc * 9) / 10;\n+\t\tcong_notif_cfg.message_ctx = 0;\n+\t\tcong_notif_cfg.message_iova =\n+\t\t\t(size_t)DPAA2_VADDR_TO_IOVA(dpaa2_q->cscn);\n+\t\tcong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE;\n+\t\tcong_notif_cfg.notification_mode =\n+\t\t\t\t\tDPNI_CONG_OPT_WRITE_MEM_ON_ENTER |\n+\t\t\t\t\tDPNI_CONG_OPT_WRITE_MEM_ON_EXIT |\n+\t\t\t\t\tDPNI_CONG_OPT_COHERENT_WRITE;\n+\t\tcong_notif_cfg.cg_point = DPNI_CP_QUEUE;\n+\n+\t\tret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW,\n+\t\t\t\t\tpriv->token,\n+\t\t\t\t\tDPNI_QUEUE_TX,\n+\t\t\t\t\t((node->parent->channel_id << 8) | tc_id),\n+\t\t\t\t\t&cong_notif_cfg);\n+\t\tif (ret) {\n+\t\t\tprintf(\"Error in setting tx congestion notification: \"\n+\t\t\t\t\"err=%d\", ret);\n+\t\t\treturn -ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+dpaa2_tm_sort_and_configure(struct rte_eth_dev *dev,\n+\t\t\t    struct dpaa2_tm_node **nodes, int n)\n+{\n+\tstruct dpaa2_tm_node *temp_node;\n+\tint i;\n+\n+\tif (n == 1) {\n+\t\tDPAA2_PMD_DEBUG(\"node id = %d\\n, priority = %d, index = %d\\n\",\n+\t\t\t\tnodes[n - 1]->id, nodes[n - 1]->priority,\n+\t\t\t\tn - 1);\n+\t\tdpaa2_tm_configure_queue(dev, nodes[n - 1]);\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < n - 1; i++) {\n+\t\tif (nodes[i]->priority > nodes[i + 1]->priority) {\n+\t\t\ttemp_node = nodes[i];\n+\t\t\tnodes[i] = nodes[i + 1];\n+\t\t\tnodes[i + 1] = temp_node;\n+\t\t}\n+\t}\n+\tdpaa2_tm_sort_and_configure(dev, nodes, n - 1);\n+\n+\tDPAA2_PMD_DEBUG(\"node id = %d\\n, priority = %d, index = %d\\n\",\n+\t\t\tnodes[n - 1]->id, nodes[n - 1]->priority,\n+\t\t\tn - 1);\n+\tdpaa2_tm_configure_queue(dev, nodes[n - 1]);\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 dpaa2_tm_node *node;\n+\tstruct dpaa2_tm_node *leaf_node, *temp_leaf_node, *channel_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+\tint ret, t;\n+\n+\t/* Populate TCs */\n+\tLIST_FOREACH(channel_node, &priv->nodes, next) {\n+\t\tstruct dpaa2_tm_node *nodes[DPNI_MAX_TC];\n+\t\tint i = 0;\n \n-\tmemset(&prio_cfg, 0, sizeof(prio_cfg));\n-\tmemset(conf, 0, sizeof(conf));\n+\t\tif (channel_node->level_id != CHANNEL_LEVEL)\n+\t\t\tcontinue;\n+\n+\t\tLIST_FOREACH(leaf_node, &priv->nodes, next) {\n+\t\t\tif (leaf_node->level_id == LNI_LEVEL ||\n+\t\t\t    leaf_node->level_id == CHANNEL_LEVEL)\n+\t\t\t\tcontinue;\n \n+\t\t\tif (leaf_node->parent == channel_node) {\n+\t\t\t\tif (i >= DPNI_MAX_TC) {\n+\t\t\t\t\tret = -rte_tm_error_set(error, EINVAL,\n+\t\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\t\"More children than supported\\n\");\n+\t\t\t\t\tgoto out;\n+\t\t\t\t}\n+\t\t\t\tnodes[i++] = leaf_node;\n+\t\t\t}\n+\t\t}\n+\t\tif (i > 0) {\n+\t\t\tDPAA2_PMD_DEBUG(\"Configure queues\\n\");\n+\t\t\tdpaa2_tm_sort_and_configure(dev, nodes, i);\n+\t\t}\n+\t}\n+\n+\t/* Shaping */\n \tLIST_FOREACH(node, &priv->nodes, next) {\n-\t\tif (node->type == 0/*root node*/) {\n+\t\tif (node->type == NON_LEAF_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+\t\t\tuint32_t param = 0;\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\t\tnode->profile->params.committed.rate /\n+\t\t\t\t(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\t/* root node */\n+\t\t\tif (node->parent == NULL) {\n+\t\t\t\tDPAA2_PMD_DEBUG(\"LNI S.rate = %u, burst =%u\\n\",\n+\t\t\t\t\t\ttx_cr_shaper.rate_limit,\n+\t\t\t\t\t\ttx_cr_shaper.max_burst_size);\n+\t\t\t\tparam = 0x2;\n+\t\t\t\tparam |= node->profile->params.pkt_length_adjust << 16;\n+\t\t\t} else {\n+\t\t\t\tDPAA2_PMD_DEBUG(\"Channel = %d S.rate = %u\\n\",\n+\t\t\t\t\t\tnode->channel_id,\n+\t\t\t\t\t\ttx_cr_shaper.rate_limit);\n+\t\t\t\tparam = (node->channel_id << 8);\n+\t\t\t}\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\t\t\t&tx_cr_shaper, &tx_er_shaper, param);\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+\t\t\tcontinue;\n+\t\t}\n+\t}\n \n+\tLIST_FOREACH(channel_node, &priv->nodes, next) {\n+\t\tint wfq_grp = 0, is_wfq_grp = 0, conf[DPNI_MAX_TC];\n+\t\tstruct dpni_tx_priorities_cfg prio_cfg;\n+\n+\t\tmemset(&prio_cfg, 0, sizeof(prio_cfg));\n+\t\tmemset(conf, 0, sizeof(conf));\n+\n+\t\t/* Process for each channel */\n+\t\tif (channel_node->level_id != CHANNEL_LEVEL)\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+\n+\t\tLIST_FOREACH(leaf_node, &priv->nodes, next) {\n+\t\t\tstruct dpaa2_queue *leaf_dpaa2_q;\n+\t\t\tuint8_t leaf_tc_id;\n+\n+\t\t\tif (leaf_node->level_id == LNI_LEVEL ||\n+\t\t\t    leaf_node->level_id == CHANNEL_LEVEL)\n+\t\t\t\tcontinue;\n+\n+\t\t\t /* level 2, all leaf nodes */\n+\t\t\tif (leaf_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\tif (conf[leaf_node->id])\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (leaf_node->parent != channel_node)\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\tleaf_dpaa2_q =  (struct dpaa2_queue *)dev->data->tx_queues[leaf_node->id];\n+\t\t\tleaf_tc_id = leaf_dpaa2_q->tc_index;\n+\t\t\t/* Process sibling leaf nodes */\n+\t\t\tLIST_FOREACH(temp_leaf_node, &priv->nodes, next) {\n+\t\t\t\tif (temp_leaf_node->id == leaf_node->id ||\n+\t\t\t\t\ttemp_leaf_node->level_id == LNI_LEVEL ||\n+\t\t\t\t\ttemp_leaf_node->level_id == CHANNEL_LEVEL)\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tif (temp_leaf_node->parent != channel_node)\n \t\t\t\t\tcontinue;\n-\t\t\t\tif (conf[temp_node->id])\n+\n+\t\t\t\tif (conf[temp_leaf_node->id])\n \t\t\t\t\tcontinue;\n-\t\t\t\tif (node->priority == temp_node->priority) {\n+\n+\t\t\t\tif (leaf_node->priority == temp_leaf_node->priority) {\n+\t\t\t\t\tstruct dpaa2_queue *temp_leaf_dpaa2_q;\n+\t\t\t\t\tuint8_t temp_leaf_tc_id;\n+\n+\t\t\t\t\ttemp_leaf_dpaa2_q = (struct dpaa2_queue *)\n+\t\t\t\t\t\tdev->data->tx_queues[temp_leaf_node->id];\n+\t\t\t\t\ttemp_leaf_tc_id = temp_leaf_dpaa2_q->tc_index;\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\tprio_cfg.tc_sched[temp_leaf_tc_id].mode =\n+\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_A;\n+\t\t\t\t\t\t/* DPAA2 support weight in multiple of 100 */\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth =\n+\t\t\t\t\t\t\ttemp_leaf_node->weight * 100;\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\tprio_cfg.tc_sched[temp_leaf_tc_id].mode =\n+\t\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_B;\n+\t\t\t\t\t\tprio_cfg.tc_sched[temp_leaf_tc_id].delta_bandwidth =\n+\t\t\t\t\t\t\ttemp_leaf_node->weight * 100;\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\tconf[temp_leaf_node->id] = 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\tprio_cfg.tc_sched[leaf_tc_id].mode =\n+\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_A;\n+\t\t\t\t\tprio_cfg.tc_sched[leaf_tc_id].delta_bandwidth =\n+\t\t\t\t\t\tleaf_node->weight * 100;\n+\t\t\t\t\tprio_cfg.prio_group_A = leaf_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\tprio_cfg.tc_sched[leaf_tc_id].mode =\n+\t\t\t\t\t\tDPNI_TX_SCHED_WEIGHTED_B;\n+\t\t\t\t\tprio_cfg.tc_sched[leaf_tc_id].delta_bandwidth =\n+\t\t\t\t\t\tleaf_node->weight * 100;\n+\t\t\t\t\tprio_cfg.prio_group_B = leaf_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\tconf[leaf_node->id] = 1;\n \t\t}\n-\t\tif (wfq_grp)\n+\t\tif (wfq_grp > 1) {\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\tif (prio_cfg.prio_group_B < prio_cfg.prio_group_A) {\n+\t\t\t\tprio_cfg.prio_group_A = 0;\n+\t\t\t\tprio_cfg.prio_group_B = 1;\n+\t\t\t} else {\n+\t\t\t\tprio_cfg.prio_group_A = 1;\n+\t\t\t\tprio_cfg.prio_group_B = 0;\n+\t\t\t}\n+\t\t}\n+\n+\t\tprio_cfg.prio_group_A = 1;\n+\t\tprio_cfg.channel_idx = channel_node->channel_id;\n+\t\tret = dpni_set_tx_priorities(dpni, 0, priv->token, &prio_cfg);\n+\t\tif (ret) {\n+\t\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\t\tgoto out;\n+\t\t}\n+\t\tDPAA2_PMD_DEBUG(\"########################################\\n\");\n+\t\tDPAA2_PMD_DEBUG(\"Channel idx = %d\\n\", prio_cfg.channel_idx);\n+\t\tfor (t = 0; t < DPNI_MAX_TC; t++) {\n+\t\t\tDPAA2_PMD_DEBUG(\"tc = %d mode = %d \", t, prio_cfg.tc_sched[t].mode);\n+\t\t\tDPAA2_PMD_DEBUG(\"delta = %d\\n\", prio_cfg.tc_sched[t].delta_bandwidth);\n+\t\t}\n+\t\tDPAA2_PMD_DEBUG(\"prioritya = %d\\n\", prio_cfg.prio_group_A);\n+\t\tDPAA2_PMD_DEBUG(\"priorityb = %d\\n\", prio_cfg.prio_group_B);\n+\t\tDPAA2_PMD_DEBUG(\"separate grps = %d\\n\\n\", prio_cfg.separate_groups);\n \t}\n-\n \treturn 0;\n \n out:\n@@ -617,6 +892,81 @@ dpaa2_hierarchy_commit(struct rte_eth_dev *dev, int clear_on_fail,\n \treturn ret;\n }\n \n+static int\n+dpaa2_node_stats_read(struct rte_eth_dev *dev, uint32_t node_id,\n+\t\t      struct rte_tm_node_stats *stats, uint64_t *stats_mask,\n+\t\t      int clear, struct rte_tm_error *error)\n+{\n+\tstruct dpaa2_dev_priv *priv = dev->data->dev_private;\n+\tstruct dpaa2_tm_node *node;\n+\tstruct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;\n+\tunion dpni_statistics value;\n+\tint ret = 0;\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\tRTE_TM_ERROR_TYPE_NODE_ID,\n+\t\t\t\tNULL, \"Node id does not exist\\n\");\n+\n+\tif (stats_mask)\n+\t\t*stats_mask = node->stats_mask;\n+\n+\tif (!stats)\n+\t\treturn 0;\n+\n+\tmemset(stats, 0, sizeof(*stats));\n+\tmemset(&value, 0, sizeof(union dpni_statistics));\n+\n+\tif (node->level_id == LNI_LEVEL) {\n+\t\tuint8_t page1 = 1;\n+\n+\t\tret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,\n+\t\t\t\t\t  page1, 0, &value);\n+\t\tif (ret)\n+\t\t\treturn -rte_tm_error_set(error, -ret,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\"Failed to read port statistics\\n\");\n+\n+\t\tif (node->stats_mask & RTE_TM_STATS_N_PKTS)\n+\t\t\tstats->n_pkts = value.page_1.egress_all_frames;\n+\n+\t\tif (node->stats_mask & RTE_TM_STATS_N_BYTES)\n+\t\t\tstats->n_bytes = value.page_1.egress_all_bytes;\n+\n+\t\tif (clear) {\n+\t\t\tret = dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token);\n+\t\t\t\treturn -rte_tm_error_set(error, -ret,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\"Failed to reset port statistics\\n\");\n+\t\t}\n+\t} else if (node->level_id == QUEUE_LEVEL) {\n+\t\tuint8_t page3 = 3;\n+\t\tstruct dpaa2_queue *dpaa2_q;\n+\t\tdpaa2_q =  (struct dpaa2_queue *)dev->data->tx_queues[node->id];\n+\n+\t\tret = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,\n+\t\t\t\t\t  page3,\n+\t\t\t\t\t  (node->parent->channel_id << 8 |\n+\t\t\t\t\t   dpaa2_q->tc_index), &value);\n+\t\tif (ret)\n+\t\t\treturn -rte_tm_error_set(error, -ret,\n+\t\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\"Failed to read queue statistics\\n\");\n+\n+\t\tif (node->stats_mask & RTE_TM_STATS_N_PKTS)\n+\t\t\tstats->n_pkts = value.page_3.ceetm_dequeue_frames;\n+\t\tif (node->stats_mask & RTE_TM_STATS_N_BYTES)\n+\t\t\tstats->n_bytes = value.page_3.ceetm_dequeue_bytes;\n+\t} else {\n+\t\treturn -rte_tm_error_set(error, -1,\n+\t\t\t\tRTE_TM_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\"Failed to read channel statistics\\n\");\n+\t}\n+\n+\treturn 0;\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@@ -627,4 +977,5 @@ const struct rte_tm_ops dpaa2_tm_ops = {\n \t.node_add = dpaa2_node_add,\n \t.node_delete = dpaa2_node_delete,\n \t.hierarchy_commit = dpaa2_hierarchy_commit,\n+\t.node_stats_read = dpaa2_node_stats_read,\n };\ndiff --git a/drivers/net/dpaa2/dpaa2_tm.h b/drivers/net/dpaa2/dpaa2_tm.h\nindex 6632fab687..cfbb437322 100644\n--- a/drivers/net/dpaa2/dpaa2_tm.h\n+++ b/drivers/net/dpaa2/dpaa2_tm.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright 2020 NXP\n+ * Copyright 2020-2021 NXP\n  */\n \n #ifndef _DPAA2_TM_H_\n@@ -7,6 +7,18 @@\n \n #include <rte_tm.h>\n \n+enum node_type {\n+\tNON_LEAF_NODE = 0,\n+\tLEAF_NODE\n+};\n+\n+enum level_type {\n+\tLNI_LEVEL = 0,\n+\tCHANNEL_LEVEL,\n+\tQUEUE_LEVEL,\n+\tMAX_LEVEL\n+};\n+\n struct dpaa2_tm_shaper_profile {\n \tLIST_ENTRY(dpaa2_tm_shaper_profile) next;\n \tuint32_t id;\n@@ -18,6 +30,9 @@ struct dpaa2_tm_node {\n \tLIST_ENTRY(dpaa2_tm_node) next;\n \tuint32_t id;\n \tuint32_t type;\n+\tuint32_t level_id;\n+\tuint16_t channel_id; /* Only for level 1 nodes */\n+\tuint16_t tc_id; /* Only for level 1 nodes */\n \tint refcnt;\n \tstruct dpaa2_tm_node *parent;\n \tstruct dpaa2_tm_shaper_profile *profile;\ndiff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c\nindex cf78295d90..b7a65cb637 100644\n--- a/drivers/net/dpaa2/mc/dpni.c\n+++ b/drivers/net/dpaa2/mc/dpni.c\n@@ -916,6 +916,44 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,\n \treturn mc_send_command(mc_io, &cmd);\n }\n \n+/**\n+ * dpni_get_link_cfg() - return the link configuration configured by\n+ *\t\t\tdpni_set_link_cfg().\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:\tLink configuration from dpni object\n+ *\n+ * Return:\t'0' on Success; Error code otherwise.\n+ */\n+int dpni_get_link_cfg(struct fsl_mc_io *mc_io,\n+\t\t      uint32_t cmd_flags,\n+\t\t      uint16_t token,\n+\t\t      struct dpni_link_cfg *cfg)\n+{\n+\tstruct mc_command cmd = { 0 };\n+\tstruct dpni_cmd_set_link_cfg *rsp_params;\n+\tint err;\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\n+\t/* send command to mc*/\n+\terr = mc_send_command(mc_io, &cmd);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* retrieve response parameters */\n+\trsp_params = (struct dpni_cmd_set_link_cfg *)cmd.params;\n+\tcfg->advertising\t= le64_to_cpu(rsp_params->advertising);\n+\tcfg->options\t\t= le64_to_cpu(rsp_params->options);\n+\tcfg->rate\t\t= le32_to_cpu(rsp_params->rate);\n+\n+\treturn err;\n+}\n+\n /**\n  * dpni_get_link_state() - Return the link state (either up or down)\n  * @mc_io:\tPointer to MC portal's I/O object\n@@ -1678,6 +1716,38 @@ int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,\n \treturn mc_send_command(mc_io, &cmd);\n }\n \n+/**\n+ * dpni_get_tx_confirmation_mode() - Get Tx confirmation mode\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+ * @mode:\tTx confirmation mode\n+ *\n+ * Return:  '0' on Success; Error code otherwise.\n+ */\n+int dpni_get_tx_confirmation_mode(struct fsl_mc_io *mc_io,\n+\t\t\t\t  uint32_t cmd_flags,\n+\t\t\t\t  uint16_t token,\n+\t\t\t\t  enum dpni_confirmation_mode *mode)\n+{\n+\tstruct dpni_tx_confirmation_mode *rsp_params;\n+\tstruct mc_command cmd = { 0 };\n+\tint err;\n+\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONFIRMATION_MODE,\n+\t\t\t\t\tcmd_flags,\n+\t\t\t\t\ttoken);\n+\n+\terr = mc_send_command(mc_io, &cmd);\n+\tif (err)\n+\t\treturn err;\n+\n+\trsp_params = (struct dpni_tx_confirmation_mode *)cmd.params;\n+\t*mode =  rsp_params->confirmation_mode;\n+\n+\treturn 0;\n+}\n+\n /**\n  * dpni_set_qos_table() - Set QoS mapping table\n  * @mc_io:\tPointer to MC portal's I/O object\n@@ -2733,6 +2803,122 @@ int dpni_get_opr(struct fsl_mc_io *mc_io,\n \treturn 0;\n }\n \n+int dpni_load_sw_sequence(struct fsl_mc_io *mc_io,\n+\t      uint32_t cmd_flags,\n+\t      uint16_t token,\n+\t\t  struct dpni_load_ss_cfg *cfg)\n+{\n+\tstruct dpni_load_sw_sequence *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_LOAD_SW_SEQUENCE,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_load_sw_sequence *)cmd.params;\n+\tcmd_params->dest = cfg->dest;\n+\tcmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);\n+\tcmd_params->ss_size = cpu_to_le16(cfg->ss_size);\n+\tcmd_params->ss_iova = cpu_to_le64(cfg->ss_iova);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n+int dpni_enable_sw_sequence(struct fsl_mc_io *mc_io,\n+\t      uint32_t cmd_flags,\n+\t      uint16_t token,\n+\t\t  struct dpni_enable_ss_cfg *cfg)\n+{\n+\tstruct dpni_enable_sw_sequence *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_SW_SEQUENCE,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\tcmd_params = (struct dpni_enable_sw_sequence *)cmd.params;\n+\tcmd_params->dest = cfg->dest;\n+\tcmd_params->set_start = cfg->set_start;\n+\tcmd_params->hxs = cpu_to_le16(cfg->hxs);\n+\tcmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);\n+\tcmd_params->param_offset = cfg->param_offset;\n+\tcmd_params->param_size = cfg->param_size;\n+\tcmd_params->param_iova = cpu_to_le64(cfg->param_iova);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n+/**\n+ * dpni_get_sw_sequence_layout() - Get the soft sequence layout\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+ * @src:\tSource of the layout (WRIOP Rx or Tx)\n+ * @ss_layout_iova:  I/O virtual address of 264 bytes DMA-able memory\n+ *\n+ * warning: After calling this function, call dpni_extract_sw_sequence_layout()\n+ *\t\tto get the layout.\n+ *\n+ * Return:\t'0' on Success; error code otherwise.\n+ */\n+int dpni_get_sw_sequence_layout(struct fsl_mc_io *mc_io,\n+\t      uint32_t cmd_flags,\n+\t      uint16_t token,\n+\t\t  enum dpni_soft_sequence_dest src,\n+\t\t  uint64_t ss_layout_iova)\n+{\n+\tstruct dpni_get_sw_sequence_layout *cmd_params;\n+\tstruct mc_command cmd = { 0 };\n+\n+\t/* prepare command */\n+\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SW_SEQUENCE_LAYOUT,\n+\t\t\t\t\t  cmd_flags,\n+\t\t\t\t\t  token);\n+\n+\tcmd_params = (struct dpni_get_sw_sequence_layout *)cmd.params;\n+\tcmd_params->src = src;\n+\tcmd_params->layout_iova = cpu_to_le64(ss_layout_iova);\n+\n+\t/* send command to mc*/\n+\treturn mc_send_command(mc_io, &cmd);\n+}\n+\n+/**\n+ * dpni_extract_sw_sequence_layout() - extract the software sequence layout\n+ * @layout:\t\tsoftware sequence layout\n+ * @sw_sequence_layout_buf:\tZeroed 264 bytes of memory before mapping it\n+ *\t\t\t\tto DMA\n+ *\n+ * This function has to be called after dpni_get_sw_sequence_layout\n+ *\n+ */\n+void dpni_extract_sw_sequence_layout(struct dpni_sw_sequence_layout *layout,\n+\t\t\t     const uint8_t *sw_sequence_layout_buf)\n+{\n+\tconst struct dpni_sw_sequence_layout_entry *ext_params;\n+\tint i;\n+\tuint16_t ss_size, ss_offset;\n+\n+\text_params = (const struct dpni_sw_sequence_layout_entry *)\n+\t\t\t\t\t\tsw_sequence_layout_buf;\n+\n+\tfor (i = 0; i < DPNI_SW_SEQUENCE_LAYOUT_SIZE; i++) {\n+\t\tss_offset = le16_to_cpu(ext_params[i].ss_offset);\n+\t\tss_size = le16_to_cpu(ext_params[i].ss_size);\n+\n+\t\tif (ss_offset == 0 && ss_size == 0) {\n+\t\t\tlayout->num_ss = i;\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tlayout->ss[i].ss_offset = ss_offset;\n+\t\tlayout->ss[i].ss_size = ss_size;\n+\t\tlayout->ss[i].param_offset = ext_params[i].param_offset;\n+\t\tlayout->ss[i].param_size = ext_params[i].param_size;\n+\t}\n+}\n /**\n  * dpni_set_rx_fs_dist() - Set Rx traffic class FS distribution\n  * @mc_io:\tPointer to MC portal's I/O object\n@@ -2901,119 +3087,3 @@ int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n \treturn err;\n }\n \n-int dpni_load_sw_sequence(struct fsl_mc_io *mc_io,\n-\t      uint32_t cmd_flags,\n-\t      uint16_t token,\n-\t\t  struct dpni_load_ss_cfg *cfg)\n-{\n-\tstruct dpni_load_sw_sequence *cmd_params;\n-\tstruct mc_command cmd = { 0 };\n-\n-\t/* prepare command */\n-\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_LOAD_SW_SEQUENCE,\n-\t\t\t\t\t  cmd_flags,\n-\t\t\t\t\t  token);\n-\tcmd_params = (struct dpni_load_sw_sequence *)cmd.params;\n-\tcmd_params->dest = cfg->dest;\n-\tcmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);\n-\tcmd_params->ss_size = cpu_to_le16(cfg->ss_size);\n-\tcmd_params->ss_iova = cpu_to_le64(cfg->ss_iova);\n-\n-\t/* send command to mc*/\n-\treturn mc_send_command(mc_io, &cmd);\n-}\n-\n-int dpni_enable_sw_sequence(struct fsl_mc_io *mc_io,\n-\t      uint32_t cmd_flags,\n-\t      uint16_t token,\n-\t\t  struct dpni_enable_ss_cfg *cfg)\n-{\n-\tstruct dpni_enable_sw_sequence *cmd_params;\n-\tstruct mc_command cmd = { 0 };\n-\n-\t/* prepare command */\n-\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_SW_SEQUENCE,\n-\t\t\t\t\t  cmd_flags,\n-\t\t\t\t\t  token);\n-\tcmd_params = (struct dpni_enable_sw_sequence *)cmd.params;\n-\tcmd_params->dest = cfg->dest;\n-\tcmd_params->set_start = cfg->set_start;\n-\tcmd_params->hxs = cpu_to_le16(cfg->hxs);\n-\tcmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);\n-\tcmd_params->param_offset = cfg->param_offset;\n-\tcmd_params->param_size = cfg->param_size;\n-\tcmd_params->param_iova = cpu_to_le64(cfg->param_iova);\n-\n-\t/* send command to mc*/\n-\treturn mc_send_command(mc_io, &cmd);\n-}\n-\n-/**\n- * dpni_get_sw_sequence_layout() - Get the soft sequence layout\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- * @src:\tSource of the layout (WRIOP Rx or Tx)\n- * @ss_layout_iova:  I/O virtual address of 264 bytes DMA-able memory\n- *\n- * warning: After calling this function, call dpni_extract_sw_sequence_layout()\n- *\t\tto get the layout.\n- *\n- * Return:\t'0' on Success; error code otherwise.\n- */\n-int dpni_get_sw_sequence_layout(struct fsl_mc_io *mc_io,\n-\t      uint32_t cmd_flags,\n-\t      uint16_t token,\n-\t\t  enum dpni_soft_sequence_dest src,\n-\t\t  uint64_t ss_layout_iova)\n-{\n-\tstruct dpni_get_sw_sequence_layout *cmd_params;\n-\tstruct mc_command cmd = { 0 };\n-\n-\t/* prepare command */\n-\tcmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SW_SEQUENCE_LAYOUT,\n-\t\t\t\t\t  cmd_flags,\n-\t\t\t\t\t  token);\n-\n-\tcmd_params = (struct dpni_get_sw_sequence_layout *)cmd.params;\n-\tcmd_params->src = src;\n-\tcmd_params->layout_iova = cpu_to_le64(ss_layout_iova);\n-\n-\t/* send command to mc*/\n-\treturn mc_send_command(mc_io, &cmd);\n-}\n-\n-/**\n- * dpni_extract_sw_sequence_layout() - extract the software sequence layout\n- * @layout:\t\tsoftware sequence layout\n- * @sw_sequence_layout_buf:\tZeroed 264 bytes of memory before mapping it\n- *\t\t\t\tto DMA\n- *\n- * This function has to be called after dpni_get_sw_sequence_layout\n- *\n- */\n-void dpni_extract_sw_sequence_layout(struct dpni_sw_sequence_layout *layout,\n-\t\t\t     const uint8_t *sw_sequence_layout_buf)\n-{\n-\tconst struct dpni_sw_sequence_layout_entry *ext_params;\n-\tint i;\n-\tuint16_t ss_size, ss_offset;\n-\n-\text_params = (const struct dpni_sw_sequence_layout_entry *)\n-\t\t\t\t\t\tsw_sequence_layout_buf;\n-\n-\tfor (i = 0; i < DPNI_SW_SEQUENCE_LAYOUT_SIZE; i++) {\n-\t\tss_offset = le16_to_cpu(ext_params[i].ss_offset);\n-\t\tss_size = le16_to_cpu(ext_params[i].ss_size);\n-\n-\t\tif (ss_offset == 0 && ss_size == 0) {\n-\t\t\tlayout->num_ss = i;\n-\t\t\treturn;\n-\t\t}\n-\n-\t\tlayout->ss[i].ss_offset = ss_offset;\n-\t\tlayout->ss[i].ss_size = ss_size;\n-\t\tlayout->ss[i].param_offset = ext_params[i].param_offset;\n-\t\tlayout->ss[i].param_size = ext_params[i].param_size;\n-\t}\n-}\ndiff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h\nindex 8aead28261..c7df727fef 100644\n--- a/drivers/net/dpaa2/mc/fsl_dpni.h\n+++ b/drivers/net/dpaa2/mc/fsl_dpni.h\n@@ -761,6 +761,11 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,\n \t\t      uint16_t token,\n \t\t      const struct dpni_link_cfg *cfg);\n \n+int dpni_get_link_cfg(struct fsl_mc_io *mc_io,\n+\t\t      uint32_t cmd_flags,\n+\t\t      uint16_t token,\n+\t\t      struct dpni_link_cfg *cfg);\n+\n /**\n  * struct dpni_link_state - Structure representing DPNI link state\n  * @rate:\tRate\n@@ -1709,63 +1714,6 @@ int dpni_get_opr(struct fsl_mc_io *mc_io,\n \t\t uint8_t flags,\n \t\t uint8_t opr_id);\n \n-/**\n- * When used for queue_idx in function dpni_set_rx_dist_default_queue will\n- * signal to dpni to drop all unclassified frames\n- */\n-#define DPNI_FS_MISS_DROP\t\t((uint16_t)-1)\n-\n-/**\n- * struct dpni_rx_dist_cfg - distribution configuration\n- * @dist_size:\tdistribution size; supported values: 1,2,3,4,6,7,8,\n- *\t\t12,14,16,24,28,32,48,56,64,96,112,128,192,224,256,384,448,\n- *\t\t512,768,896,1024\n- * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with\n- *\t\tthe extractions to be used for the distribution key by calling\n- *\t\tdpkg_prepare_key_cfg() relevant only when enable!=0 otherwise\n- *\t\tit can be '0'\n- * @enable: enable/disable the distribution.\n- * @tc: TC id for which distribution is set\n- * @fs_miss_flow_id: when packet misses all rules from flow steering table and\n- *\t\thash is disabled it will be put into this queue id; use\n- *\t\tDPNI_FS_MISS_DROP to drop frames. The value of this field is\n- *\t\tused only when flow steering distribution is enabled and hash\n- *\t\tdistribution is disabled\n- */\n-struct dpni_rx_dist_cfg {\n-\tuint16_t dist_size;\n-\tuint64_t key_cfg_iova;\n-\tuint8_t enable;\n-\tuint8_t tc;\n-\tuint16_t fs_miss_flow_id;\n-};\n-\n-int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n-\t\tuint16_t token, const struct dpni_rx_dist_cfg *cfg);\n-\n-int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n-\t\tuint16_t token, const struct dpni_rx_dist_cfg *cfg);\n-\n-int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n-\t\tuint16_t token, uint16_t tpid);\n-\n-int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n-\t\tuint16_t token, uint16_t tpid);\n-\n-/**\n- * struct dpni_custom_tpid_cfg - custom TPID configuration. Contains custom TPID\n- *\tvalues used in current dpni object to detect 802.1q frames.\n- *\t@tpid1: first tag. Not used if zero.\n- *\t@tpid2: second tag. Not used if zero.\n- */\n-struct dpni_custom_tpid_cfg {\n-\tuint16_t tpid1;\n-\tuint16_t tpid2;\n-};\n-\n-int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n-\t\tuint16_t token, struct dpni_custom_tpid_cfg *tpid);\n-\n /**\n  * enum dpni_soft_sequence_dest - Enumeration of WRIOP software sequence\n  *\t\t\t\tdestinations\n@@ -1936,4 +1884,61 @@ int dpni_set_port_cfg(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n int dpni_get_port_cfg(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n \t\tuint16_t token, struct dpni_port_cfg *port_cfg);\n \n+/**\n+ * When used for queue_idx in function dpni_set_rx_dist_default_queue will\n+ * signal to dpni to drop all unclassified frames\n+ */\n+#define DPNI_FS_MISS_DROP\t\t((uint16_t)-1)\n+\n+/**\n+ * struct dpni_rx_dist_cfg - distribution configuration\n+ * @dist_size:\tdistribution size; supported values: 1,2,3,4,6,7,8,\n+ *\t\t12,14,16,24,28,32,48,56,64,96,112,128,192,224,256,384,448,\n+ *\t\t512,768,896,1024\n+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with\n+ *\t\tthe extractions to be used for the distribution key by calling\n+ *\t\tdpkg_prepare_key_cfg() relevant only when enable!=0 otherwise\n+ *\t\tit can be '0'\n+ * @enable: enable/disable the distribution.\n+ * @tc: TC id for which distribution is set\n+ * @fs_miss_flow_id: when packet misses all rules from flow steering table and\n+ *\t\thash is disabled it will be put into this queue id; use\n+ *\t\tDPNI_FS_MISS_DROP to drop frames. The value of this field is\n+ *\t\tused only when flow steering distribution is enabled and hash\n+ *\t\tdistribution is disabled\n+ */\n+struct dpni_rx_dist_cfg {\n+\tuint16_t dist_size;\n+\tuint64_t key_cfg_iova;\n+\tuint8_t enable;\n+\tuint8_t tc;\n+\tuint16_t fs_miss_flow_id;\n+};\n+\n+int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n+\t\tuint16_t token, const struct dpni_rx_dist_cfg *cfg);\n+\n+int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n+\t\tuint16_t token, const struct dpni_rx_dist_cfg *cfg);\n+\n+int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n+\t\tuint16_t token, uint16_t tpid);\n+\n+int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n+\t\tuint16_t token, uint16_t tpid);\n+\n+/**\n+ * struct dpni_custom_tpid_cfg - custom TPID configuration. Contains custom TPID\n+ *\tvalues used in current dpni object to detect 802.1q frames.\n+ *\t@tpid1: first tag. Not used if zero.\n+ *\t@tpid2: second tag. Not used if zero.\n+ */\n+struct dpni_custom_tpid_cfg {\n+\tuint16_t tpid1;\n+\tuint16_t tpid2;\n+};\n+\n+int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,\n+\t\tuint16_t token, struct dpni_custom_tpid_cfg *tpid);\n+\n #endif /* __FSL_DPNI_H */\ndiff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\nindex 8bff2ec9af..ed0bd7615a 100644\n--- a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\n+++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h\n@@ -108,16 +108,17 @@\n #define DPNI_CMDID_SET_OFFLOAD\t\t\tDPNI_CMD(0x26C)\n #define DPNI_CMDID_SET_TX_CONFIRMATION_MODE\tDPNI_CMD(0x266)\n #define DPNI_CMDID_GET_TX_CONFIRMATION_MODE\tDPNI_CMD(0x26D)\n+#define DPNI_CMDID_SET_OPR\t\t\tDPNI_CMD(0x26e)\n+#define DPNI_CMDID_GET_OPR\t\t\tDPNI_CMD(0x26f)\n #define DPNI_CMDID_LOAD_SW_SEQUENCE\t\tDPNI_CMD(0x270)\n #define DPNI_CMDID_ENABLE_SW_SEQUENCE\t\tDPNI_CMD(0x271)\n #define DPNI_CMDID_GET_SW_SEQUENCE_LAYOUT\tDPNI_CMD(0x272)\n-#define DPNI_CMDID_SET_OPR\t\t\tDPNI_CMD(0x26e)\n-#define DPNI_CMDID_GET_OPR\t\t\tDPNI_CMD(0x26f)\n #define DPNI_CMDID_SET_RX_FS_DIST\t\tDPNI_CMD(0x273)\n #define DPNI_CMDID_SET_RX_HASH_DIST\t\tDPNI_CMD(0x274)\n #define DPNI_CMDID_ADD_CUSTOM_TPID\t\tDPNI_CMD(0x275)\n #define DPNI_CMDID_REMOVE_CUSTOM_TPID\t\tDPNI_CMD(0x276)\n #define DPNI_CMDID_GET_CUSTOM_TPID\t\tDPNI_CMD(0x277)\n+#define DPNI_CMDID_GET_LINK_CFG\t\t\tDPNI_CMD(0x278)\n \n /* Macros for accessing command fields smaller than 1byte */\n #define DPNI_MASK(field)\t\\\n@@ -451,8 +452,6 @@ struct dpni_cmd_enable_vlan_filter {\n \tuint8_t en;\n };\n \n-#define DPNI_VLAN_SET_QUEUE_ACTION 1\n-\n struct dpni_cmd_vlan_id {\n \tuint8_t flags;\n \tuint8_t tc_id;\n@@ -854,42 +853,6 @@ struct dpni_rsp_get_opr {\n \tuint16_t opr_id;\n };\n \n-struct dpni_cmd_add_custom_tpid {\n-\tuint16_t\tpad;\n-\tuint16_t\ttpid;\n-};\n-\n-struct dpni_cmd_remove_custom_tpid {\n-\tuint16_t\tpad;\n-\tuint16_t\ttpid;\n-};\n-\n-struct dpni_rsp_get_custom_tpid {\n-\tuint16_t\ttpid1;\n-\tuint16_t\ttpid2;\n-};\n-\n-#define DPNI_RX_FS_DIST_ENABLE_SHIFT\t0\n-#define DPNI_RX_FS_DIST_ENABLE_SIZE\t\t1\n-struct dpni_cmd_set_rx_fs_dist {\n-\tuint16_t\tdist_size;\n-\tuint8_t\t\tenable;\n-\tuint8_t\t\ttc;\n-\tuint16_t\tmiss_flow_id;\n-\tuint16_t\tpad1;\n-\tuint64_t\tkey_cfg_iova;\n-};\n-\n-#define DPNI_RX_HASH_DIST_ENABLE_SHIFT\t0\n-#define DPNI_RX_HASH_DIST_ENABLE_SIZE\t\t1\n-struct dpni_cmd_set_rx_hash_dist {\n-\tuint16_t\tdist_size;\n-\tuint8_t\t\tenable;\n-\tuint8_t\t\ttc_id;\n-\tuint32_t\tpad;\n-\tuint64_t\tkey_cfg_iova;\n-};\n-\n struct dpni_load_sw_sequence {\n \tuint8_t dest;\n \tuint8_t pad0[7];\n@@ -957,5 +920,41 @@ struct dpni_rsp_get_port_cfg {\n \tuint32_t\tbit_params;\n };\n \n+#define DPNI_RX_FS_DIST_ENABLE_SHIFT\t0\n+#define DPNI_RX_FS_DIST_ENABLE_SIZE\t\t1\n+struct dpni_cmd_set_rx_fs_dist {\n+\tuint16_t\tdist_size;\n+\tuint8_t\t\tenable;\n+\tuint8_t\t\ttc;\n+\tuint16_t\tmiss_flow_id;\n+\tuint16_t\tpad1;\n+\tuint64_t\tkey_cfg_iova;\n+};\n+\n+#define DPNI_RX_HASH_DIST_ENABLE_SHIFT\t0\n+#define DPNI_RX_HASH_DIST_ENABLE_SIZE\t\t1\n+struct dpni_cmd_set_rx_hash_dist {\n+\tuint16_t\tdist_size;\n+\tuint8_t\t\tenable;\n+\tuint8_t\t\ttc_id;\n+\tuint32_t\tpad;\n+\tuint64_t\tkey_cfg_iova;\n+};\n+\n+struct dpni_cmd_add_custom_tpid {\n+\tuint16_t\tpad;\n+\tuint16_t\ttpid;\n+};\n+\n+struct dpni_cmd_remove_custom_tpid {\n+\tuint16_t\tpad;\n+\tuint16_t\ttpid;\n+};\n+\n+struct dpni_rsp_get_custom_tpid {\n+\tuint16_t\ttpid1;\n+\tuint16_t\ttpid2;\n+};\n+\n #pragma pack(pop)\n #endif /* _FSL_DPNI_CMD_H */\n",
    "prefixes": [
        "07/17"
    ]
}