get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130814,
    "url": "https://patches.dpdk.org/api/patches/130814/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230829075829.208413-23-wanry@3snic.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20230829075829.208413-23-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230829075829.208413-23-wanry@3snic.com",
    "date": "2023-08-29T07:58:19",
    "name": "[22/32] net/sssnic: add basic and extended stats ops",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0e672966ec131fd66b1ec9e960cd9a8e4e1f0f24",
    "submitter": {
        "id": 3119,
        "url": "https://patches.dpdk.org/api/people/3119/?format=api",
        "name": "Renyong Wan",
        "email": "wanry@3snic.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230829075829.208413-23-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29358,
            "url": "https://patches.dpdk.org/api/series/29358/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29358",
            "date": "2023-08-29T07:57:57",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/29358/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/130814/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/130814/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 E0E5841F53;\n\tTue, 29 Aug 2023 10:03:28 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 12530402AB;\n\tTue, 29 Aug 2023 10:02:13 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id C4B1A4029A\n for <dev@dpdk.org>; Tue, 29 Aug 2023 10:02:09 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 37T7wrMF080563;\n Tue, 29 Aug 2023 15:59:28 +0800 (GMT-8)\n (envelope-from wanry@3snic.com)",
            "from localhost.localdomain (10.64.136.151) by\n V12DG1MBS03.ramaxel.local (172.26.18.33) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id\n 15.1.2375.17; Tue, 29 Aug 2023 15:58:46 +0800"
        ],
        "From": "<wanry@3snic.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@amd.com>, Renyong Wan <wanry@3snic.com>, Steven Song\n <steven.song@3snic.com>",
        "Subject": "[PATCH 22/32] net/sssnic: add basic and extended stats ops",
        "Date": "Tue, 29 Aug 2023 15:58:19 +0800",
        "Message-ID": "<20230829075829.208413-23-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230829075829.208413-1-wanry@3snic.com>",
        "References": "<20230829075829.208413-1-wanry@3snic.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "7bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.136.151]",
        "X-ClientProxiedBy": "V12DG1MBS03.ramaxel.local (172.26.18.33) To\n V12DG1MBS03.ramaxel.local (172.26.18.33)",
        "X-DNSRBL": "",
        "X-SPAM-SOURCE-CHECK": "pass",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 37T7wrMF080563",
        "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: Renyong Wan <wanry@3snic.com>\n\nSigned-off-by: Steven Song <steven.song@3snic.com>\nSigned-off-by: Renyong Wan <wanry@3snic.com>\n---\n doc/guides/nics/features/sssnic.ini      |   3 +\n drivers/net/sssnic/base/sssnic_api.c     | 154 +++++++++\n drivers/net/sssnic/base/sssnic_api.h     | 116 +++++++\n drivers/net/sssnic/base/sssnic_cmd.h     |  12 +\n drivers/net/sssnic/meson.build           |   1 +\n drivers/net/sssnic/sssnic_ethdev.c       |   6 +\n drivers/net/sssnic/sssnic_ethdev_rx.c    |  30 ++\n drivers/net/sssnic/sssnic_ethdev_rx.h    |   4 +\n drivers/net/sssnic/sssnic_ethdev_stats.c | 392 +++++++++++++++++++++++\n drivers/net/sssnic/sssnic_ethdev_stats.h |  18 ++\n drivers/net/sssnic/sssnic_ethdev_tx.c    |  36 +++\n drivers/net/sssnic/sssnic_ethdev_tx.h    |   4 +\n 12 files changed, 776 insertions(+)\n create mode 100644 drivers/net/sssnic/sssnic_ethdev_stats.c\n create mode 100644 drivers/net/sssnic/sssnic_ethdev_stats.h",
    "diff": "diff --git a/doc/guides/nics/features/sssnic.ini b/doc/guides/nics/features/sssnic.ini\nindex 359834ce4c..aba0b78c95 100644\n--- a/doc/guides/nics/features/sssnic.ini\n+++ b/doc/guides/nics/features/sssnic.ini\n@@ -12,6 +12,9 @@ Promiscuous mode     = Y\n Allmulticast mode    = Y\n Unicast MAC filter   = Y\n Multicast MAC filter = Y\n+Basic stats          = Y\n+Extended stats       = Y\n+Stats per queue      = Y\n Linux                = Y\n ARMv8                = Y\n x86-64               = Y\ndiff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c\nindex 81020387bd..9f063112f2 100644\n--- a/drivers/net/sssnic/base/sssnic_api.c\n+++ b/drivers/net/sssnic/base/sssnic_api.c\n@@ -1005,3 +1005,157 @@ sssnic_port_resource_clean(struct sssnic_hw *hw)\n \n \treturn 0;\n }\n+\n+int\n+sssnic_port_stats_get(struct sssnic_hw *hw, struct sssnic_port_stats *stats)\n+{\n+\tint ret;\n+\tstruct sssnic_port_stats_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len, resp_len;\n+\tstruct {\n+\t\tstruct sssnic_cmd_common common;\n+\t\tuint32_t size;\n+\t\tuint32_t resvd0;\n+\t\tstruct sssnic_port_stats stats;\n+\t\tuint64_t rsvd1[6];\n+\t} resp;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_GET_PORT_STATS_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tmemset(&resp, 0, sizeof(resp));\n+\tresp_len = sizeof(resp);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&resp, &resp_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (resp_len == 0 || resp.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_GET_PORT_STATS_CMD, len=%u, status=%u\",\n+\t\t\tresp_len, resp.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\tmemcpy(stats, &resp.stats, sizeof(resp.stats));\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_port_stats_clear(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_port_stats_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_CLEAR_PORT_STATS_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_CLEAN_PORT_RES_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_mac_stats_get(struct sssnic_hw *hw, struct sssnic_mac_stats *stats)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len, resp_len;\n+\tstruct sssnic_mac_stats_cmd cmd;\n+\tstruct {\n+\t\tstruct sssnic_cmd_common common;\n+\t\tstruct sssnic_mac_stats stats;\n+\t\tuint64_t resvd[15];\n+\t} *resp;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.port = SSSNIC_PHY_PORT(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_GET_NETIF_MAC_STATS_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_NETIF_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tresp_len = sizeof(*resp);\n+\tresp = rte_zmalloc(NULL, resp_len, 0);\n+\tif (resp == NULL) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to alloc memory for mac stats response cmd\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)resp, &resp_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\tgoto out;\n+\t}\n+\n+\tif (resp_len == 0 || resp->common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_GET_NETIF_MAC_STATS_CMD, len=%u, status=%u\",\n+\t\t\tresp_len, resp->common.status);\n+\t\tret = -EIO;\n+\t\tgoto out;\n+\t}\n+\n+\tmemcpy(stats, &resp->stats, sizeof(resp->stats));\n+\n+out:\n+\trte_free(resp);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_mac_stats_clear(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_mac_stats_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.port = SSSNIC_PHY_PORT(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_CLEAR_NETIF_MAC_STATS_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_NETIF_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_CLEAR_NETIF_MAC_STATS_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h\nindex 49336f70cf..c2f4f90209 100644\n--- a/drivers/net/sssnic/base/sssnic_api.h\n+++ b/drivers/net/sssnic/base/sssnic_api.h\n@@ -267,6 +267,117 @@ struct sssnic_rxtxq_ctx {\n \n #define SSSNIC_RXTXQ_CTX_SIZE (sizeof(struct sssnic_rxtxq_ctx))\n \n+struct sssnic_port_stats {\n+\tuint64_t tx_ucast_pkts;\n+\tuint64_t tx_ucast_bytes;\n+\tuint64_t tx_mcast_pkts;\n+\tuint64_t tx_mcast_bytes;\n+\tuint64_t tx_bcast_pkts;\n+\tuint64_t tx_bcast_bytes;\n+\n+\tuint64_t rx_ucast_pkts;\n+\tuint64_t rx_ucast_bytes;\n+\tuint64_t rx_mcast_pkts;\n+\tuint64_t rx_mcast_bytes;\n+\tuint64_t rx_bcast_pkts;\n+\tuint64_t rx_bcast_bytes;\n+\n+\tuint64_t tx_discards;\n+\tuint64_t rx_discards;\n+\tuint64_t tx_errors;\n+\tuint64_t rx_errors;\n+};\n+\n+struct sssnic_mac_stats {\n+\tuint64_t tx_fragment_pkts;\n+\tuint64_t tx_undersize_pkts;\n+\tuint64_t tx_undermin_pkts;\n+\tuint64_t tx_64b_pkts;\n+\tuint64_t tx_65b_127b_pkt;\n+\tuint64_t tx_128b_255b_pkts;\n+\tuint64_t tx_256b_511b_pkts;\n+\tuint64_t tx_512b_1023b_pkts;\n+\tuint64_t tx_1024b_1518b_pkts;\n+\tuint64_t tx_1519b_2047b_pkts;\n+\tuint64_t tx_2048b_4095b_pkts;\n+\tuint64_t tx_4096b_8191b_pkts;\n+\tuint64_t tx_8192b_9216b_pkts;\n+\tuint64_t tx_9217b_12287b_pkts;\n+\tuint64_t tx_12288b_16383b_pkts;\n+\tuint64_t tx_1519b_bad_pkts;\n+\tuint64_t tx_1519b_good_pkts;\n+\tuint64_t tx_oversize_pkts;\n+\tuint64_t tx_jabber_pkts;\n+\tuint64_t tx_bad_pkts;\n+\tuint64_t tx_bad_bytes;\n+\tuint64_t tx_good_pkts;\n+\tuint64_t tx_good_bytes;\n+\tuint64_t tx_total_pkts;\n+\tuint64_t tx_total_bytes;\n+\tuint64_t tx_unicast_pkts;\n+\tuint64_t tx_multicast_bytes;\n+\tuint64_t tx_broadcast_pkts;\n+\tuint64_t tx_pause_pkts;\n+\tuint64_t tx_pfc_pkts;\n+\tuint64_t tx_pfc_pri0_pkts;\n+\tuint64_t tx_pfc_pri1_pkts;\n+\tuint64_t tx_pfc_pri2_pkts;\n+\tuint64_t tx_pfc_pri3_pkts;\n+\tuint64_t tx_pfc_pri4_pkts;\n+\tuint64_t tx_pfc_pri5_pkts;\n+\tuint64_t tx_pfc_pri6_pkts;\n+\tuint64_t tx_pfc_pri7_pkts;\n+\tuint64_t tx_control_pkts;\n+\tuint64_t tx_total_error_pkts;\n+\tuint64_t tx_debug_good_pkts;\n+\tuint64_t tx_debug_bad_pkts;\n+\n+\tuint64_t rx_fragment_pkts;\n+\tuint64_t rx_undersize_pkts;\n+\tuint64_t rx_undermin_pkts;\n+\tuint64_t rx_64b_pkts;\n+\tuint64_t rx_65b_127b_pkt;\n+\tuint64_t rx_128b_255b_pkts;\n+\tuint64_t rx_256b_511b_pkts;\n+\tuint64_t rx_512b_1023b_pkts;\n+\tuint64_t rx_1024b_1518b_pkts;\n+\tuint64_t rx_1519b_2047b_pkts;\n+\tuint64_t rx_2048b_4095b_pkts;\n+\tuint64_t rx_4096b_8191b_pkts;\n+\tuint64_t rx_8192b_9216b_pkts;\n+\tuint64_t rx_9217b_12287b_pkts;\n+\tuint64_t rx_12288b_16383b_pkts;\n+\tuint64_t rx_1519b_bad_pkts;\n+\tuint64_t rx_1519b_good_pkts;\n+\tuint64_t rx_oversize_pkts;\n+\tuint64_t rx_jabber_pkts;\n+\tuint64_t rx_bad_pkts;\n+\tuint64_t rx_bad_bytes;\n+\tuint64_t rx_good_pkts;\n+\tuint64_t rx_good_bytes;\n+\tuint64_t rx_total_pkts;\n+\tuint64_t rx_total_bytes;\n+\tuint64_t rx_unicast_pkts;\n+\tuint64_t rx_multicast_bytes;\n+\tuint64_t rx_broadcast_pkts;\n+\tuint64_t rx_pause_pkts;\n+\tuint64_t rx_pfc_pkts;\n+\tuint64_t rx_pfc_pri0_pkts;\n+\tuint64_t rx_pfc_pri1_pkts;\n+\tuint64_t rx_pfc_pri2_pkts;\n+\tuint64_t rx_pfc_pri3_pkts;\n+\tuint64_t rx_pfc_pri4_pkts;\n+\tuint64_t rx_pfc_pri5_pkts;\n+\tuint64_t rx_pfc_pri6_pkts;\n+\tuint64_t rx_pfc_pri7_pkts;\n+\tuint64_t rx_control_pkts;\n+\tuint64_t rx_symbol_error_pkts;\n+\tuint64_t rx_fcs_error_pkts;\n+\tuint64_t rx_debug_good_pkts;\n+\tuint64_t rx_debug_bad_pkts;\n+\tuint64_t rx_unfilter_pkts;\n+};\n+\n int sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,\n \tstruct sssnic_msix_attr *attr);\n int sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,\n@@ -304,5 +415,10 @@ int sssnic_lro_timer_set(struct sssnic_hw *hw, uint32_t timer);\n int sssnic_vlan_filter_enable_set(struct sssnic_hw *hw, bool state);\n int sssnic_vlan_strip_enable_set(struct sssnic_hw *hw, bool state);\n int sssnic_port_resource_clean(struct sssnic_hw *hw);\n+int sssnic_port_stats_get(struct sssnic_hw *hw,\n+\tstruct sssnic_port_stats *stats);\n+int sssnic_port_stats_clear(struct sssnic_hw *hw);\n+int sssnic_mac_stats_get(struct sssnic_hw *hw, struct sssnic_mac_stats *stats);\n+int sssnic_mac_stats_clear(struct sssnic_hw *hw);\n \n #endif /* _SSSNIC_API_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h\nindex e89719b0de..bc7303ff57 100644\n--- a/drivers/net/sssnic/base/sssnic_cmd.h\n+++ b/drivers/net/sssnic/base/sssnic_cmd.h\n@@ -336,4 +336,16 @@ struct sssnic_port_resource_clean_cmd {\n \tuint16_t resvd;\n };\n \n+struct sssnic_port_stats_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd;\n+};\n+\n+struct sssnic_mac_stats_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint8_t port;\n+\tuint8_t resvd[3];\n+};\n+\n #endif /* _SSSNIC_CMD_H_ */\ndiff --git a/drivers/net/sssnic/meson.build b/drivers/net/sssnic/meson.build\nindex 0c6e21310d..dea24f4b06 100644\n--- a/drivers/net/sssnic/meson.build\n+++ b/drivers/net/sssnic/meson.build\n@@ -21,4 +21,5 @@ sources = files(\n         'sssnic_ethdev_link.c',\n         'sssnic_ethdev_rx.c',\n         'sssnic_ethdev_tx.c',\n+        'sssnic_ethdev_stats.c',\n )\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c\nindex 242a1bfb92..5503cbd902 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.c\n+++ b/drivers/net/sssnic/sssnic_ethdev.c\n@@ -13,6 +13,7 @@\n #include \"sssnic_ethdev_link.h\"\n #include \"sssnic_ethdev_rx.h\"\n #include \"sssnic_ethdev_tx.h\"\n+#include \"sssnic_ethdev_stats.h\"\n \n static int sssnic_ethdev_init(struct rte_eth_dev *ethdev);\n \n@@ -749,6 +750,11 @@ static const struct eth_dev_ops sssnic_ethdev_ops = {\n \t.allmulticast_disable = sssnic_ethdev_allmulticast_disable,\n \t.promiscuous_enable = sssnic_ethdev_promiscuous_enable,\n \t.promiscuous_disable = sssnic_ethdev_promiscuous_disable,\n+\t.stats_get = sssnic_ethdev_stats_get,\n+\t.stats_reset = sssnic_ethdev_stats_reset,\n+\t.xstats_get_names = sssnic_ethdev_xstats_get_names,\n+\t.xstats_get = sssnic_ethdev_xstats_get,\n+\t.xstats_reset = sssnic_ethdev_xstats_reset,\n };\n \n static int\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rx.c b/drivers/net/sssnic/sssnic_ethdev_rx.c\nindex 18d193dd0c..d6e8940593 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_rx.c\n+++ b/drivers/net/sssnic/sssnic_ethdev_rx.c\n@@ -1154,3 +1154,33 @@ sssnic_ethdev_rx_offload_setup(struct rte_eth_dev *ethdev)\n \n \treturn 0;\n }\n+\n+int\n+sssnic_ethdev_rx_queue_stats_get(struct rte_eth_dev *ethdev, uint16_t qid,\n+\tstruct sssnic_ethdev_rxq_stats *stats)\n+{\n+\tstruct sssnic_ethdev_rxq *rxq;\n+\n+\tif (qid >= ethdev->data->nb_rx_queues) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Invalid qid, qid must less than nb_rx_queues(%u)\",\n+\t\t\tethdev->data->nb_rx_queues);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trxq = ethdev->data->rx_queues[qid];\n+\tmemcpy(stats, &rxq->stats, sizeof(rxq->stats));\n+\n+\treturn 0;\n+}\n+\n+void\n+sssnic_ethdev_rx_queue_stats_clear(struct rte_eth_dev *ethdev, uint16_t qid)\n+{\n+\tstruct sssnic_ethdev_rxq *rxq;\n+\n+\tif (qid < ethdev->data->nb_rx_queues) {\n+\t\trxq = ethdev->data->rx_queues[qid];\n+\t\tmemset(&rxq->stats, 0, sizeof(rxq->stats));\n+\t}\n+};\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rx.h b/drivers/net/sssnic/sssnic_ethdev_rx.h\nindex f4b4545944..5532aced4e 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_rx.h\n+++ b/drivers/net/sssnic/sssnic_ethdev_rx.h\n@@ -38,5 +38,9 @@ uint16_t sssnic_ethdev_rx_queue_depth_get(struct rte_eth_dev *ethdev,\n uint32_t sssnic_ethdev_rx_buf_size_index_get(uint16_t rx_buf_size);\n int sssnic_ethdev_rx_mode_set(struct rte_eth_dev *ethdev, uint32_t mode);\n int sssnic_ethdev_rx_offload_setup(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_rx_queue_stats_get(struct rte_eth_dev *ethdev, uint16_t qid,\n+\tstruct sssnic_ethdev_rxq_stats *stats);\n+void sssnic_ethdev_rx_queue_stats_clear(struct rte_eth_dev *ethdev,\n+\tuint16_t qid);\n \n #endif\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_stats.c b/drivers/net/sssnic/sssnic_ethdev_stats.c\nnew file mode 100644\nindex 0000000000..3397a6f62e\n--- /dev/null\n+++ b/drivers/net/sssnic/sssnic_ethdev_stats.c\n@@ -0,0 +1,392 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <error.h>\n+#include <rte_common.h>\n+#include <ethdev_pci.h>\n+\n+#include \"sssnic_log.h\"\n+#include \"sssnic_ethdev.h\"\n+#include \"sssnic_ethdev_rx.h\"\n+#include \"sssnic_ethdev_tx.h\"\n+#include \"sssnic_ethdev_stats.h\"\n+#include \"base/sssnic_hw.h\"\n+#include \"base/sssnic_api.h\"\n+\n+struct sssnic_ethdev_xstats_name_off {\n+\tchar name[RTE_ETH_XSTATS_NAME_SIZE];\n+\tuint32_t offset;\n+};\n+\n+#define SSSNIC_ETHDEV_XSTATS_STR_OFF(stats_type, field)                        \\\n+\t{ #field, offsetof(struct stats_type, field) }\n+\n+#define SSSNIC_ETHDEV_XSTATS_VALUE(data, idx, name_off)                        \\\n+\t(*(uint64_t *)(((uint8_t *)(data)) + (name_off)[idx].offset))\n+\n+#define SSSNIC_ETHDEV_RXQ_STATS_STR_OFF(field)                                 \\\n+\tSSSNIC_ETHDEV_XSTATS_STR_OFF(sssnic_ethdev_rxq_stats, field)\n+\n+#define SSSNIC_ETHDEV_TXQ_STATS_STR_OFF(field)                                 \\\n+\tSSSNIC_ETHDEV_XSTATS_STR_OFF(sssnic_ethdev_txq_stats, field)\n+\n+#define SSSNIC_ETHDEV_PORT_STATS_STR_OFF(field)                                \\\n+\tSSSNIC_ETHDEV_XSTATS_STR_OFF(sssnic_port_stats, field)\n+\n+#define SSSNIC_ETHDEV_MAC_STATS_STR_OFF(field)                                 \\\n+\tSSSNIC_ETHDEV_XSTATS_STR_OFF(sssnic_mac_stats, field)\n+\n+static const struct sssnic_ethdev_xstats_name_off rxq_stats_strings[] = {\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(packets),\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(bytes),\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(csum_errors),\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(other_errors),\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(nombuf),\n+\tSSSNIC_ETHDEV_RXQ_STATS_STR_OFF(burst),\n+};\n+#define SSSNIC_ETHDEV_NB_RXQ_XSTATS RTE_DIM(rxq_stats_strings)\n+\n+static const struct sssnic_ethdev_xstats_name_off txq_stats_strings[] = {\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(packets),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(bytes),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(nobuf),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(zero_len_segs),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(too_large_pkts),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(too_many_segs),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(null_segs),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(offload_errors),\n+\tSSSNIC_ETHDEV_TXQ_STATS_STR_OFF(burst),\n+};\n+#define SSSNIC_ETHDEV_NB_TXQ_XSTATS RTE_DIM(txq_stats_strings)\n+\n+static const struct sssnic_ethdev_xstats_name_off port_stats_strings[] = {\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_ucast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_ucast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_mcast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_mcast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_bcast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_bcast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_discards),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(rx_errors),\n+\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_ucast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_ucast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_mcast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_mcast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_bcast_pkts),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_bcast_bytes),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_discards),\n+\tSSSNIC_ETHDEV_PORT_STATS_STR_OFF(tx_errors),\n+};\n+#define SSSNIC_ETHDEV_NB_PORT_XSTATS RTE_DIM(port_stats_strings)\n+\n+static const struct sssnic_ethdev_xstats_name_off mac_stats_strings[] = {\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_fragment_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_undersize_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_undermin_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_64b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_65b_127b_pkt),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_128b_255b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_256b_511b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_512b_1023b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_1024b_1518b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_1519b_2047b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_2048b_4095b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_4096b_8191b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_8192b_9216b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_9217b_12287b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_12288b_16383b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_1519b_bad_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_1519b_good_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_oversize_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_jabber_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_bad_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_bad_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_good_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_good_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_total_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_total_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_unicast_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_multicast_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_broadcast_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pause_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri0_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri1_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri2_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri3_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri4_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri5_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri6_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_pfc_pri7_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_control_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_symbol_error_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_fcs_error_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(rx_unfilter_pkts),\n+\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_fragment_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_undersize_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_undermin_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_64b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_65b_127b_pkt),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_128b_255b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_256b_511b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_512b_1023b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_1024b_1518b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_1519b_2047b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_2048b_4095b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_4096b_8191b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_8192b_9216b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_9217b_12287b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_12288b_16383b_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_1519b_bad_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_1519b_good_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_oversize_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_jabber_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_bad_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_bad_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_good_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_good_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_total_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_total_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_unicast_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_multicast_bytes),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_broadcast_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pause_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri0_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri1_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri2_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri3_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri4_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri5_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri6_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_pfc_pri7_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_control_pkts),\n+\tSSSNIC_ETHDEV_MAC_STATS_STR_OFF(tx_debug_bad_pkts),\n+};\n+#define SSSNIC_ETHDEV_NB_MAC_XSTATS RTE_DIM(mac_stats_strings)\n+\n+int\n+sssnic_ethdev_stats_get(struct rte_eth_dev *ethdev, struct rte_eth_stats *stats)\n+{\n+\tstruct sssnic_port_stats port_stats;\n+\tstruct sssnic_ethdev_rxq_stats rxq_stats;\n+\tstruct sssnic_ethdev_txq_stats txq_stats;\n+\tint ret;\n+\tuint16_t numq, qid;\n+\n+\tret = sssnic_port_stats_get(SSSNIC_ETHDEV_TO_HW(ethdev), &port_stats);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get port stats\");\n+\t\treturn ret;\n+\t}\n+\n+\tstats->ipackets = port_stats.rx_ucast_pkts + port_stats.rx_mcast_pkts +\n+\t\t\t  port_stats.rx_bcast_pkts;\n+\tstats->ibytes = port_stats.rx_ucast_bytes + port_stats.rx_mcast_bytes +\n+\t\t\tport_stats.rx_bcast_bytes;\n+\tstats->opackets = port_stats.tx_ucast_pkts + port_stats.tx_mcast_pkts +\n+\t\t\t  port_stats.tx_bcast_pkts;\n+\tstats->obytes = port_stats.tx_ucast_bytes + port_stats.tx_mcast_bytes +\n+\t\t\tport_stats.tx_bcast_bytes;\n+\n+\tstats->imissed = port_stats.rx_discards;\n+\tstats->oerrors = port_stats.tx_discards;\n+\n+\tethdev->data->rx_mbuf_alloc_failed = 0;\n+\n+\tnumq = RTE_MIN(ethdev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);\n+\tfor (qid = 0; qid < numq; qid++) {\n+\t\tsssnic_ethdev_rx_queue_stats_get(ethdev, qid, &rxq_stats);\n+\t\tstats->q_ipackets[qid] = rxq_stats.packets;\n+\t\tstats->q_ibytes[qid] = rxq_stats.bytes;\n+\t\tstats->ierrors +=\n+\t\t\trxq_stats.csum_errors + rxq_stats.other_errors;\n+\t\tethdev->data->rx_mbuf_alloc_failed += rxq_stats.nombuf;\n+\t}\n+\n+\tnumq = RTE_MIN(ethdev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);\n+\tfor (qid = 0; qid < numq; qid++) {\n+\t\tsssnic_ethdev_tx_queue_stats_get(ethdev, qid, &txq_stats);\n+\t\tstats->q_opackets[qid] = txq_stats.packets;\n+\t\tstats->q_obytes[qid] = txq_stats.bytes;\n+\t\tstats->oerrors += txq_stats.nobuf + txq_stats.too_large_pkts +\n+\t\t\t\t  txq_stats.zero_len_segs +\n+\t\t\t\t  txq_stats.offload_errors +\n+\t\t\t\t  txq_stats.null_segs + txq_stats.too_many_segs;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_ethdev_stats_reset(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\tuint16_t numq, qid;\n+\n+\tret = sssnic_port_stats_clear(SSSNIC_ETHDEV_TO_HW(ethdev));\n+\tif (ret)\n+\t\tPMD_DRV_LOG(ERR, \"Failed to clear port stats\");\n+\n+\tnumq = RTE_MIN(ethdev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);\n+\tfor (qid = 0; qid < numq; qid++)\n+\t\tsssnic_ethdev_rx_queue_stats_clear(ethdev, qid);\n+\n+\tnumq = RTE_MIN(ethdev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);\n+\tfor (qid = 0; qid < numq; qid++)\n+\t\tsssnic_ethdev_tx_queue_stats_clear(ethdev, qid);\n+\n+\treturn 0;\n+}\n+\n+static uint32_t\n+sssnic_ethdev_xstats_num_calc(struct rte_eth_dev *ethdev)\n+{\n+\treturn SSSNIC_ETHDEV_NB_PORT_XSTATS + SSSNIC_ETHDEV_NB_MAC_XSTATS +\n+\t       (SSSNIC_ETHDEV_NB_TXQ_XSTATS * ethdev->data->nb_tx_queues) +\n+\t       (SSSNIC_ETHDEV_NB_RXQ_XSTATS * ethdev->data->nb_rx_queues);\n+}\n+\n+int\n+sssnic_ethdev_xstats_get_names(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_xstat_name *xstats_names,\n+\t__rte_unused unsigned int limit)\n+{\n+\tuint16_t i, qid, count = 0;\n+\n+\tif (xstats_names == NULL)\n+\t\treturn sssnic_ethdev_xstats_num_calc(ethdev);\n+\n+\tfor (qid = 0; qid < ethdev->data->nb_rx_queues; qid++) {\n+\t\tfor (i = 0; i < SSSNIC_ETHDEV_NB_RXQ_XSTATS; i++) {\n+\t\t\tsnprintf(xstats_names[count].name,\n+\t\t\t\tRTE_ETH_XSTATS_NAME_SIZE, \"rx_q%u_%s\", qid,\n+\t\t\t\trxq_stats_strings[i].name);\n+\t\t\tcount++;\n+\t\t}\n+\t}\n+\n+\tfor (qid = 0; qid < ethdev->data->nb_tx_queues; qid++) {\n+\t\tfor (i = 0; i < SSSNIC_ETHDEV_NB_TXQ_XSTATS; i++) {\n+\t\t\tsnprintf(xstats_names[count].name,\n+\t\t\t\tRTE_ETH_XSTATS_NAME_SIZE, \"tx_q%u_%s\", qid,\n+\t\t\t\ttxq_stats_strings[i].name);\n+\t\t\tcount++;\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_NB_PORT_XSTATS; i++) {\n+\t\tsnprintf(xstats_names[count].name, RTE_ETH_XSTATS_NAME_SIZE,\n+\t\t\t\"port_%s\", port_stats_strings[i].name);\n+\t\tcount++;\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_NB_MAC_XSTATS; i++) {\n+\t\tsnprintf(xstats_names[count].name, RTE_ETH_XSTATS_NAME_SIZE,\n+\t\t\t\"mac_%s\", mac_stats_strings[i].name);\n+\t\tcount++;\n+\t}\n+\n+\treturn count;\n+}\n+\n+int\n+sssnic_ethdev_xstats_get(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_xstat *xstats, unsigned int n)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tint ret;\n+\tuint16_t i, qid, count = 0;\n+\tstruct {\n+\t\tstruct sssnic_ethdev_rxq_stats rxq;\n+\t\tstruct sssnic_ethdev_txq_stats txq;\n+\t\tstruct sssnic_port_stats port;\n+\t\tstruct sssnic_mac_stats mac;\n+\t} *stats;\n+\n+\tif (n < sssnic_ethdev_xstats_num_calc(ethdev))\n+\t\treturn count;\n+\n+\tstats = rte_zmalloc(NULL, sizeof(*stats), 0);\n+\tif (stats == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for xstats\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (qid = 0; qid < ethdev->data->nb_rx_queues; qid++) {\n+\t\tsssnic_ethdev_rx_queue_stats_get(ethdev, qid, &stats->rxq);\n+\t\tfor (i = 0; i < SSSNIC_ETHDEV_NB_RXQ_XSTATS; i++) {\n+\t\t\txstats[count].value =\n+\t\t\t\tSSSNIC_ETHDEV_XSTATS_VALUE(&stats->rxq, i,\n+\t\t\t\t\trxq_stats_strings);\n+\t\t\tcount++;\n+\t\t}\n+\t}\n+\n+\tfor (qid = 0; qid < ethdev->data->nb_tx_queues; qid++) {\n+\t\tsssnic_ethdev_tx_queue_stats_get(ethdev, qid, &stats->txq);\n+\t\tfor (i = 0; i < SSSNIC_ETHDEV_NB_TXQ_XSTATS; i++) {\n+\t\t\txstats[count].value =\n+\t\t\t\tSSSNIC_ETHDEV_XSTATS_VALUE(&stats->txq,\n+\t\t\t\t\ti, txq_stats_strings);\n+\t\t\tcount++;\n+\t\t}\n+\t}\n+\n+\tret = sssnic_port_stats_get(hw, &stats->port);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get port %u stats\",\n+\t\t\tethdev->data->port_id);\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_NB_PORT_XSTATS; i++) {\n+\t\txstats[count].value = SSSNIC_ETHDEV_XSTATS_VALUE(&stats->port,\n+\t\t\ti, port_stats_strings);\n+\t\tcount++;\n+\t}\n+\n+\tret = sssnic_mac_stats_get(hw, &stats->mac);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get port %u mac stats\",\n+\t\t\tethdev->data->port_id);\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_NB_MAC_XSTATS; i++) {\n+\t\txstats[count].value = SSSNIC_ETHDEV_XSTATS_VALUE(&stats->mac, i,\n+\t\t\tmac_stats_strings);\n+\t\tcount++;\n+\t}\n+\n+\tret = count;\n+\n+out:\n+\trte_free(stats);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_xstats_reset(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\n+\tret = sssnic_ethdev_stats_reset(ethdev);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to clear port %u  basic stats\",\n+\t\t\tethdev->data->port_id);\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_mac_stats_clear(SSSNIC_ETHDEV_TO_HW(ethdev));\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to clear port %u MAC stats\",\n+\t\t\tethdev->data->port_id);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_stats.h b/drivers/net/sssnic/sssnic_ethdev_stats.h\nnew file mode 100644\nindex 0000000000..2fdc419e60\n--- /dev/null\n+++ b/drivers/net/sssnic/sssnic_ethdev_stats.h\n@@ -0,0 +1,18 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_ETHDEV_STATS_H_\n+#define _SSSNIC_ETHDEV_STATS_H_\n+\n+int sssnic_ethdev_stats_get(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_stats *stats);\n+int sssnic_ethdev_stats_reset(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_xstats_get_names(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_xstat_name *xstats_names,\n+\t__rte_unused unsigned int limit);\n+int sssnic_ethdev_xstats_get(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_xstat *xstats, unsigned int n);\n+int sssnic_ethdev_xstats_reset(struct rte_eth_dev *ethdev);\n+\n+#endif /* _SSSNIC_ETHDEV_STATS_H_ */\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_tx.c b/drivers/net/sssnic/sssnic_ethdev_tx.c\nindex c75943ebf2..ea70bbcbbc 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_tx.c\n+++ b/drivers/net/sssnic/sssnic_ethdev_tx.c\n@@ -671,3 +671,39 @@ sssnic_ethdev_tx_max_size_set(struct rte_eth_dev *ethdev, uint16_t size)\n \n \treturn 0;\n };\n+\n+int\n+sssnic_ethdev_tx_queue_stats_get(struct rte_eth_dev *ethdev, uint16_t qid,\n+\tstruct sssnic_ethdev_txq_stats *stats)\n+{\n+\tstruct sssnic_ethdev_txq *txq;\n+\n+\tif (qid >= ethdev->data->nb_tx_queues) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Invalid qid, qid must less than nb_tx_queues(%u)\",\n+\t\t\tethdev->data->nb_tx_queues);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttxq = ethdev->data->tx_queues[qid];\n+\tmemcpy(stats, &txq->stats, sizeof(txq->stats));\n+\n+\treturn 0;\n+}\n+\n+void\n+sssnic_ethdev_tx_queue_stats_clear(struct rte_eth_dev *ethdev, uint16_t qid)\n+{\n+\tstruct sssnic_ethdev_txq *txq;\n+\tuint64_t *stat;\n+\tint i, len;\n+\n+\tlen = sizeof(struct sssnic_ethdev_txq_stats) / sizeof(uint64_t);\n+\n+\tif (qid < ethdev->data->nb_tx_queues) {\n+\t\ttxq = ethdev->data->tx_queues[qid];\n+\t\tstat = (uint64_t *)&txq->stats;\n+\t\tfor (i = 0; i < len; i++)\n+\t\t\t*(stat++) = 0;\n+\t}\n+}\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_tx.h b/drivers/net/sssnic/sssnic_ethdev_tx.h\nindex 88ad82a055..f04c3d5be8 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_tx.h\n+++ b/drivers/net/sssnic/sssnic_ethdev_tx.h\n@@ -33,5 +33,9 @@ uint16_t sssnic_ethdev_tx_queue_depth_get(struct rte_eth_dev *ethdev,\n \tuint16_t qid);\n int sssnic_ethdev_tx_ci_attr_init(struct rte_eth_dev *ethdev);\n int sssnic_ethdev_tx_max_size_set(struct rte_eth_dev *ethdev, uint16_t size);\n+int sssnic_ethdev_tx_queue_stats_get(struct rte_eth_dev *ethdev, uint16_t qid,\n+\tstruct sssnic_ethdev_txq_stats *stats);\n+void sssnic_ethdev_tx_queue_stats_clear(struct rte_eth_dev *ethdev,\n+\tuint16_t qid);\n \n #endif /* _SSSNIC_ETHDEV_TX_H_ */\n",
    "prefixes": [
        "22/32"
    ]
}