From patchwork Thu Dec 30 06:09:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yanling Song X-Patchwork-Id: 105523 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 404CFA00C5; Thu, 30 Dec 2021 07:12:04 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D113642705; Thu, 30 Dec 2021 07:10:06 +0100 (CET) Received: from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186]) by mails.dpdk.org (Postfix) with ESMTP id 73952426F5 for ; Thu, 30 Dec 2021 07:10:03 +0100 (CET) Received: from V12DG1MBS01.ramaxel.local (v12dg1mbs01.ramaxel.local [172.26.18.31]) by VLXDG1SPAM1.ramaxel.com with ESMTPS id 1BU69DWm040086 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 30 Dec 2021 14:09:15 +0800 (GMT-8) (envelope-from songyl@ramaxel.com) Received: from localhost.localdomain (10.64.9.47) by V12DG1MBS01.ramaxel.local (172.26.18.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Thu, 30 Dec 2021 14:09:14 +0800 From: Yanling Song To: CC: , , , , , , Subject: [PATCH v6 22/26] net/spnic: net/spnic: support xstats statistics Date: Thu, 30 Dec 2021 14:09:00 +0800 Message-ID: <09fbdf0128576eff14be3914f176101ec823e054.1640838702.git.songyl@ramaxel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.64.9.47] X-ClientProxiedBy: V12DG1MBS03.ramaxel.local (172.26.18.33) To V12DG1MBS01.ramaxel.local (172.26.18.31) X-DNSRBL: X-MAIL: VLXDG1SPAM1.ramaxel.com 1BU69DWm040086 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This commit implements DFX statistics of physical port, function, Rx queues and Tx queues, which includes MAC statistic, unicast/multicast/broadcast packets statistic, rx_mbuf, tx_busy and etc. Signed-off-by: Yanling Song --- drivers/net/spnic/base/spnic_nic_cfg.c | 118 ++++++ drivers/net/spnic/base/spnic_nic_cfg.h | 206 +++++++++++ drivers/net/spnic/spnic_ethdev.c | 474 +++++++++++++++++++++++++ 3 files changed, 798 insertions(+) diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c index 52ad2d1148..32d52bd81e 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.c +++ b/drivers/net/spnic/base/spnic_nic_cfg.c @@ -493,6 +493,124 @@ int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause) return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause); } +int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats) +{ + struct spnic_port_stats_info stats_info; + struct spnic_cmd_vport_stats vport_stats; + u16 out_size = sizeof(vport_stats); + int err; + + if (!hwdev || !stats) + return -EINVAL; + + memset(&stats_info, 0, sizeof(stats_info)); + memset(&vport_stats, 0, sizeof(vport_stats)); + + stats_info.func_id = spnic_global_func_id(hwdev); + + err = spnic_l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_GET_VPORT_STAT, + &stats_info, sizeof(stats_info), + &vport_stats, &out_size); + if (err || !out_size || vport_stats.msg_head.status) { + PMD_DRV_LOG(ERR, "Get function stats failed, err: %d, status: 0x%x, out size: 0x%x", + err, vport_stats.msg_head.status, out_size); + return -EIO; + } + + memcpy(stats, &vport_stats.stats, sizeof(*stats)); + + return 0; +} + +int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats) +{ + struct mag_cmd_get_port_stat *port_stats = NULL; + struct mag_cmd_port_stats_info stats_info; + u16 out_size = sizeof(*port_stats); + int err; + + port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0); + if (!port_stats) + return -ENOMEM; + + memset(&stats_info, 0, sizeof(stats_info)); + stats_info.port_id = spnic_physical_port_id(hwdev); + + err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, + &stats_info, sizeof(stats_info), + port_stats, &out_size); + if (err || !out_size || port_stats->head.status) { + PMD_DRV_LOG(ERR, + "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", + err, port_stats->head.status, out_size); + err = -EIO; + goto out; + } + + memcpy(stats, &port_stats->counter, sizeof(*stats)); + +out: + rte_free(port_stats); + + return err; +} + +int spnic_clear_vport_stats(void *hwdev) +{ + struct spnic_cmd_clear_vport_stats clear_vport_stats; + u16 out_size = sizeof(clear_vport_stats); + int err; + + if (!hwdev) { + PMD_DRV_LOG(ERR, "Hwdev is NULL"); + return -EINVAL; + } + + memset(&clear_vport_stats, 0, sizeof(clear_vport_stats)); + clear_vport_stats.func_id = spnic_global_func_id(hwdev); + + err = spnic_l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAN_VPORT_STAT, + &clear_vport_stats, + sizeof(clear_vport_stats), + &clear_vport_stats, &out_size); + if (err || !out_size || clear_vport_stats.msg_head.status) { + PMD_DRV_LOG(ERR, "Clear vport stats failed, err: %d, status: 0x%x, out size: 0x%x", + err, clear_vport_stats.msg_head.status, out_size); + return -EIO; + } + + return 0; +} + +int spnic_clear_phy_port_stats(void *hwdev) +{ + struct mag_cmd_clr_port_stat *port_stats = NULL; + u16 out_size = sizeof(*port_stats); + int err; + + port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0); + if (!port_stats) + return -ENOMEM; + + port_stats->port_id = spnic_physical_port_id(hwdev); + + err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, + &port_stats, sizeof(port_stats), + port_stats, &out_size); + if (err || !out_size || port_stats->head.status) { + PMD_DRV_LOG(ERR, + "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", + err, port_stats->head.status, out_size); + err = -EIO; + goto out; + } + +out: + rte_free(port_stats); + + return err; +} + static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap, struct spnic_func_tbl_cfg *cfg) { diff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h index 2e00bdece5..3c996e2838 100644 --- a/drivers/net/spnic/base/spnic_nic_cfg.h +++ b/drivers/net/spnic/base/spnic_nic_cfg.h @@ -259,6 +259,160 @@ struct spnic_cmd_clear_qp_resource { u16 rsvd1; }; +struct spnic_port_stats_info { + struct mgmt_msg_head msg_head; + + u16 func_id; + u16 rsvd1; +}; + +struct spnic_vport_stats { + u64 tx_unicast_pkts_vport; + u64 tx_unicast_bytes_vport; + u64 tx_multicast_pkts_vport; + u64 tx_multicast_bytes_vport; + u64 tx_broadcast_pkts_vport; + u64 tx_broadcast_bytes_vport; + + u64 rx_unicast_pkts_vport; + u64 rx_unicast_bytes_vport; + u64 rx_multicast_pkts_vport; + u64 rx_multicast_bytes_vport; + u64 rx_broadcast_pkts_vport; + u64 rx_broadcast_bytes_vport; + + u64 tx_discard_vport; + u64 rx_discard_vport; + u64 tx_err_vport; + u64 rx_err_vport; +}; + +struct spnic_cmd_vport_stats { + struct mgmt_msg_head msg_head; + + u32 stats_size; + u32 rsvd1; + struct spnic_vport_stats stats; + u64 rsvd2[6]; +}; + +struct mag_phy_port_stats { + u64 mac_tx_fragment_pkt_num; + u64 mac_tx_undersize_pkt_num; + u64 mac_tx_undermin_pkt_num; + u64 mac_tx_64_oct_pkt_num; + u64 mac_tx_65_127_oct_pkt_num; + u64 mac_tx_128_255_oct_pkt_num; + u64 mac_tx_256_511_oct_pkt_num; + u64 mac_tx_512_1023_oct_pkt_num; + u64 mac_tx_1024_1518_oct_pkt_num; + u64 mac_tx_1519_2047_oct_pkt_num; + u64 mac_tx_2048_4095_oct_pkt_num; + u64 mac_tx_4096_8191_oct_pkt_num; + u64 mac_tx_8192_9216_oct_pkt_num; + u64 mac_tx_9217_12287_oct_pkt_num; + u64 mac_tx_12288_16383_oct_pkt_num; + u64 mac_tx_1519_max_bad_pkt_num; + u64 mac_tx_1519_max_good_pkt_num; + u64 mac_tx_oversize_pkt_num; + u64 mac_tx_jabber_pkt_num; + u64 mac_tx_bad_pkt_num; + u64 mac_tx_bad_oct_num; + u64 mac_tx_good_pkt_num; + u64 mac_tx_good_oct_num; + u64 mac_tx_total_pkt_num; + u64 mac_tx_total_oct_num; + u64 mac_tx_uni_pkt_num; + u64 mac_tx_multi_pkt_num; + u64 mac_tx_broad_pkt_num; + u64 mac_tx_pause_num; + u64 mac_tx_pfc_pkt_num; + u64 mac_tx_pfc_pri0_pkt_num; + u64 mac_tx_pfc_pri1_pkt_num; + u64 mac_tx_pfc_pri2_pkt_num; + u64 mac_tx_pfc_pri3_pkt_num; + u64 mac_tx_pfc_pri4_pkt_num; + u64 mac_tx_pfc_pri5_pkt_num; + u64 mac_tx_pfc_pri6_pkt_num; + u64 mac_tx_pfc_pri7_pkt_num; + u64 mac_tx_control_pkt_num; + u64 mac_tx_err_all_pkt_num; + u64 mac_tx_from_app_good_pkt_num; + u64 mac_tx_from_app_bad_pkt_num; + + u64 mac_rx_fragment_pkt_num; + u64 mac_rx_undersize_pkt_num; + u64 mac_rx_undermin_pkt_num; + u64 mac_rx_64_oct_pkt_num; + u64 mac_rx_65_127_oct_pkt_num; + u64 mac_rx_128_255_oct_pkt_num; + u64 mac_rx_256_511_oct_pkt_num; + u64 mac_rx_512_1023_oct_pkt_num; + u64 mac_rx_1024_1518_oct_pkt_num; + u64 mac_rx_1519_2047_oct_pkt_num; + u64 mac_rx_2048_4095_oct_pkt_num; + u64 mac_rx_4096_8191_oct_pkt_num; + u64 mac_rx_8192_9216_oct_pkt_num; + u64 mac_rx_9217_12287_oct_pkt_num; + u64 mac_rx_12288_16383_oct_pkt_num; + u64 mac_rx_1519_max_bad_pkt_num; + u64 mac_rx_1519_max_good_pkt_num; + u64 mac_rx_oversize_pkt_num; + u64 mac_rx_jabber_pkt_num; + u64 mac_rx_bad_pkt_num; + u64 mac_rx_bad_oct_num; + u64 mac_rx_good_pkt_num; + u64 mac_rx_good_oct_num; + u64 mac_rx_total_pkt_num; + u64 mac_rx_total_oct_num; + u64 mac_rx_uni_pkt_num; + u64 mac_rx_multi_pkt_num; + u64 mac_rx_broad_pkt_num; + u64 mac_rx_pause_num; + u64 mac_rx_pfc_pkt_num; + u64 mac_rx_pfc_pri0_pkt_num; + u64 mac_rx_pfc_pri1_pkt_num; + u64 mac_rx_pfc_pri2_pkt_num; + u64 mac_rx_pfc_pri3_pkt_num; + u64 mac_rx_pfc_pri4_pkt_num; + u64 mac_rx_pfc_pri5_pkt_num; + u64 mac_rx_pfc_pri6_pkt_num; + u64 mac_rx_pfc_pri7_pkt_num; + u64 mac_rx_control_pkt_num; + u64 mac_rx_sym_err_pkt_num; + u64 mac_rx_fcs_err_pkt_num; + u64 mac_rx_send_app_good_pkt_num; + u64 mac_rx_send_app_bad_pkt_num; + u64 mac_rx_unfilter_pkt_num; +}; + +struct mag_cmd_port_stats_info { + struct mgmt_msg_head head; + + u8 port_id; + u8 rsvd0[3]; +}; + +struct mag_cmd_get_port_stat { + struct mgmt_msg_head head; + + struct mag_phy_port_stats counter; + u64 rsvd1[15]; +}; + +struct mag_cmd_clr_port_stat { + struct mgmt_msg_head head; + + u8 port_id; + u8 rsvd0[3]; +}; + +struct spnic_cmd_clear_vport_stats { + struct mgmt_msg_head msg_head; + + u16 func_id; + u16 rsvd; +}; enum spnic_func_tbl_cfg_bitmap { FUNC_CFG_INIT, @@ -586,6 +740,58 @@ int spnic_set_pause_info(void *hwdev, struct nic_pause_config nic_pause); */ int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause); +/** + * Get function stats + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[out] stats + * Function stats + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats); + +/** + * Get port stats + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[out] stats + * Port stats + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats); + +/** + * Clear function stats + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[out] stats + * Function stats + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_clear_vport_stats(void *hwdev); + +/** + * Clear port stats + * + * @param[in] hwdev + * Device pointer to hwdev + * @param[out] stats + * Port stats + * + * @retval zero : Success + * @retval non-zero : Failure + */ +int spnic_clear_phy_port_stats(void *hwdev); + /** * Init nic hwdev * diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c index 820f34da2f..0565a7876e 100644 --- a/drivers/net/spnic/spnic_ethdev.c +++ b/drivers/net/spnic/spnic_ethdev.c @@ -66,6 +66,171 @@ enum spnic_rx_mod { #define SPNIC_DEFAULT_RX_MODE (SPNIC_RX_MODE_UC | SPNIC_RX_MODE_MC | \ SPNIC_RX_MODE_BC) +struct spnic_xstats_name_off { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + u32 offset; +}; + +#define SPNIC_FUNC_STAT(_stat_item) { \ + .name = #_stat_item, \ + .offset = offsetof(struct spnic_vport_stats, _stat_item) \ +} + +#define SPNIC_PORT_STAT(_stat_item) { \ + .name = #_stat_item, \ + .offset = offsetof(struct mag_phy_port_stats, _stat_item) \ +} + +static const struct spnic_xstats_name_off spnic_vport_stats_strings[] = { + SPNIC_FUNC_STAT(tx_unicast_pkts_vport), + SPNIC_FUNC_STAT(tx_unicast_bytes_vport), + SPNIC_FUNC_STAT(tx_multicast_pkts_vport), + SPNIC_FUNC_STAT(tx_multicast_bytes_vport), + SPNIC_FUNC_STAT(tx_broadcast_pkts_vport), + SPNIC_FUNC_STAT(tx_broadcast_bytes_vport), + + SPNIC_FUNC_STAT(rx_unicast_pkts_vport), + SPNIC_FUNC_STAT(rx_unicast_bytes_vport), + SPNIC_FUNC_STAT(rx_multicast_pkts_vport), + SPNIC_FUNC_STAT(rx_multicast_bytes_vport), + SPNIC_FUNC_STAT(rx_broadcast_pkts_vport), + SPNIC_FUNC_STAT(rx_broadcast_bytes_vport), + + SPNIC_FUNC_STAT(tx_discard_vport), + SPNIC_FUNC_STAT(rx_discard_vport), + SPNIC_FUNC_STAT(tx_err_vport), + SPNIC_FUNC_STAT(rx_err_vport), +}; + +#define SPNIC_VPORT_XSTATS_NUM (sizeof(spnic_vport_stats_strings) / \ + sizeof(spnic_vport_stats_strings[0])) + +static const struct spnic_xstats_name_off spnic_phyport_stats_strings[] = { + SPNIC_PORT_STAT(mac_tx_fragment_pkt_num), + SPNIC_PORT_STAT(mac_tx_undersize_pkt_num), + SPNIC_PORT_STAT(mac_tx_undermin_pkt_num), + SPNIC_PORT_STAT(mac_tx_64_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_65_127_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_128_255_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_256_511_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num), + SPNIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num), + SPNIC_PORT_STAT(mac_tx_1519_max_good_pkt_num), + SPNIC_PORT_STAT(mac_tx_oversize_pkt_num), + SPNIC_PORT_STAT(mac_tx_jabber_pkt_num), + SPNIC_PORT_STAT(mac_tx_bad_pkt_num), + SPNIC_PORT_STAT(mac_tx_bad_oct_num), + SPNIC_PORT_STAT(mac_tx_good_pkt_num), + SPNIC_PORT_STAT(mac_tx_good_oct_num), + SPNIC_PORT_STAT(mac_tx_total_pkt_num), + SPNIC_PORT_STAT(mac_tx_total_oct_num), + SPNIC_PORT_STAT(mac_tx_uni_pkt_num), + SPNIC_PORT_STAT(mac_tx_multi_pkt_num), + SPNIC_PORT_STAT(mac_tx_broad_pkt_num), + SPNIC_PORT_STAT(mac_tx_pause_num), + SPNIC_PORT_STAT(mac_tx_pfc_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num), + SPNIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num), + SPNIC_PORT_STAT(mac_tx_control_pkt_num), + SPNIC_PORT_STAT(mac_tx_err_all_pkt_num), + SPNIC_PORT_STAT(mac_tx_from_app_good_pkt_num), + SPNIC_PORT_STAT(mac_tx_from_app_bad_pkt_num), + + SPNIC_PORT_STAT(mac_rx_fragment_pkt_num), + SPNIC_PORT_STAT(mac_rx_undersize_pkt_num), + SPNIC_PORT_STAT(mac_rx_undermin_pkt_num), + SPNIC_PORT_STAT(mac_rx_64_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_65_127_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_128_255_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_256_511_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num), + SPNIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num), + SPNIC_PORT_STAT(mac_rx_1519_max_good_pkt_num), + SPNIC_PORT_STAT(mac_rx_oversize_pkt_num), + SPNIC_PORT_STAT(mac_rx_jabber_pkt_num), + SPNIC_PORT_STAT(mac_rx_bad_pkt_num), + SPNIC_PORT_STAT(mac_rx_bad_oct_num), + SPNIC_PORT_STAT(mac_rx_good_pkt_num), + SPNIC_PORT_STAT(mac_rx_good_oct_num), + SPNIC_PORT_STAT(mac_rx_total_pkt_num), + SPNIC_PORT_STAT(mac_rx_total_oct_num), + SPNIC_PORT_STAT(mac_rx_uni_pkt_num), + SPNIC_PORT_STAT(mac_rx_multi_pkt_num), + SPNIC_PORT_STAT(mac_rx_broad_pkt_num), + SPNIC_PORT_STAT(mac_rx_pause_num), + SPNIC_PORT_STAT(mac_rx_pfc_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num), + SPNIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num), + SPNIC_PORT_STAT(mac_rx_control_pkt_num), + SPNIC_PORT_STAT(mac_rx_sym_err_pkt_num), + SPNIC_PORT_STAT(mac_rx_fcs_err_pkt_num), + SPNIC_PORT_STAT(mac_rx_send_app_good_pkt_num), + SPNIC_PORT_STAT(mac_rx_send_app_bad_pkt_num), + SPNIC_PORT_STAT(mac_rx_unfilter_pkt_num) +}; + +#define SPNIC_PHYPORT_XSTATS_NUM (sizeof(spnic_phyport_stats_strings) / \ + sizeof(spnic_phyport_stats_strings[0])) + +static const struct spnic_xstats_name_off spnic_rxq_stats_strings[] = { + {"rx_nombuf", offsetof(struct spnic_rxq_stats, rx_nombuf)}, + {"burst_pkt", offsetof(struct spnic_rxq_stats, burst_pkts)}, +}; + +#define SPNIC_RXQ_XSTATS_NUM (sizeof(spnic_rxq_stats_strings) / \ + sizeof(spnic_rxq_stats_strings[0])) + +static const struct spnic_xstats_name_off spnic_txq_stats_strings[] = { + {"tx_busy", offsetof(struct spnic_txq_stats, tx_busy)}, + {"offload_errors", offsetof(struct spnic_txq_stats, off_errs)}, + {"burst_pkts", offsetof(struct spnic_txq_stats, burst_pkts)}, + {"sge_len0", offsetof(struct spnic_txq_stats, sge_len0)}, + {"mbuf_null", offsetof(struct spnic_txq_stats, mbuf_null)}, +}; + +#define SPNIC_TXQ_XSTATS_NUM (sizeof(spnic_txq_stats_strings) / \ + sizeof(spnic_txq_stats_strings[0])) + +static int spnic_xstats_calc_num(struct spnic_nic_dev *nic_dev) +{ + if (SPNIC_IS_VF(nic_dev->hwdev)) { + return (SPNIC_VPORT_XSTATS_NUM + + SPNIC_RXQ_XSTATS_NUM * nic_dev->num_rqs + + SPNIC_TXQ_XSTATS_NUM * nic_dev->num_sqs); + } else { + return (SPNIC_VPORT_XSTATS_NUM + + SPNIC_PHYPORT_XSTATS_NUM + + SPNIC_RXQ_XSTATS_NUM * nic_dev->num_rqs + + SPNIC_TXQ_XSTATS_NUM * nic_dev->num_sqs); + } +} + #define SPNIC_MAX_QUEUE_DEPTH 16384 #define SPNIC_MIN_QUEUE_DEPTH 128 #define SPNIC_TXD_ALIGN 1 @@ -1827,6 +1992,305 @@ static int spnic_rss_reta_update(struct rte_eth_dev *dev, return err; } +/** + * Get device generic statistics. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[out] stats + * Stats structure output buffer. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_stats_get(struct rte_eth_dev *dev, + struct rte_eth_stats *stats) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct spnic_vport_stats vport_stats; + struct spnic_rxq *rxq = NULL; + struct spnic_txq *txq = NULL; + int i, err, q_num; + u64 rx_discards_pmd = 0; + + err = spnic_get_vport_stats(nic_dev->hwdev, &vport_stats); + if (err) { + PMD_DRV_LOG(ERR, "Get vport stats from fw failed, nic_dev: %s", + nic_dev->dev_name); + return err; + } + + dev->data->rx_mbuf_alloc_failed = 0; + + /* Rx queue stats */ + q_num = (nic_dev->num_rqs < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? + nic_dev->num_rqs : RTE_ETHDEV_QUEUE_STAT_CNTRS; + for (i = 0; i < q_num; i++) { + rxq = nic_dev->rxqs[i]; + stats->q_ipackets[i] = rxq->rxq_stats.packets; + stats->q_ibytes[i] = rxq->rxq_stats.bytes; + stats->q_errors[i] = rxq->rxq_stats.dropped; + + stats->ierrors += rxq->rxq_stats.errors; + rx_discards_pmd += rxq->rxq_stats.dropped; + dev->data->rx_mbuf_alloc_failed += rxq->rxq_stats.rx_nombuf; + } + + /* Tx queue stats */ + q_num = (nic_dev->num_sqs < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? + nic_dev->num_sqs : RTE_ETHDEV_QUEUE_STAT_CNTRS; + for (i = 0; i < q_num; i++) { + txq = nic_dev->txqs[i]; + stats->q_opackets[i] = txq->txq_stats.packets; + stats->q_obytes[i] = txq->txq_stats.bytes; + stats->oerrors += (txq->txq_stats.tx_busy + + txq->txq_stats.off_errs); + } + + /* Vport stats */ + stats->oerrors += vport_stats.tx_discard_vport; + + stats->imissed = vport_stats.rx_discard_vport + rx_discards_pmd; + + stats->ipackets = (vport_stats.rx_unicast_pkts_vport + + vport_stats.rx_multicast_pkts_vport + + vport_stats.rx_broadcast_pkts_vport - + rx_discards_pmd); + + stats->opackets = (vport_stats.tx_unicast_pkts_vport + + vport_stats.tx_multicast_pkts_vport + + vport_stats.tx_broadcast_pkts_vport); + + stats->ibytes = (vport_stats.rx_unicast_bytes_vport + + vport_stats.rx_multicast_bytes_vport + + vport_stats.rx_broadcast_bytes_vport); + + stats->obytes = (vport_stats.tx_unicast_bytes_vport + + vport_stats.tx_multicast_bytes_vport + + vport_stats.tx_broadcast_bytes_vport); + return 0; +} + +/** + * Clear device generic statistics. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_stats_reset(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct spnic_rxq *rxq = NULL; + struct spnic_txq *txq = NULL; + int qid; + int err; + + err = spnic_clear_vport_stats(nic_dev->hwdev); + if (err) + return err; + + for (qid = 0; qid < nic_dev->num_rqs; qid++) { + rxq = nic_dev->rxqs[qid]; + memset(&rxq->rxq_stats, 0, sizeof(struct spnic_rxq_stats)); + } + + for (qid = 0; qid < nic_dev->num_sqs; qid++) { + txq = nic_dev->txqs[qid]; + memset(&txq->txq_stats, 0, sizeof(struct spnic_txq_stats)); + } + + return 0; +} + +/** + * Get device extended statistics. + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[out] xstats + * Pointer to rte extended stats table. + * @param[in] n + * The size of the stats table. + * + * @retval positive: Number of extended stats on success and stats is filled + * @retval negative: Failure + */ +static int spnic_dev_xstats_get(struct rte_eth_dev *dev, + struct rte_eth_xstat *xstats, unsigned int n) +{ + struct spnic_nic_dev *nic_dev; + struct mag_phy_port_stats port_stats; + struct spnic_vport_stats vport_stats; + struct spnic_rxq *rxq = NULL; + struct spnic_rxq_stats rxq_stats; + struct spnic_txq *txq = NULL; + struct spnic_txq_stats txq_stats; + u16 qid; + u32 i; + int err, count; + + nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + count = spnic_xstats_calc_num(nic_dev); + if ((int)n < count) + return count; + + count = 0; + + /* Get stats from rxq stats structure */ + for (qid = 0; qid < nic_dev->num_rqs; qid++) { + rxq = nic_dev->rxqs[qid]; + memcpy(&rxq_stats, &rxq->rxq_stats, sizeof(rxq->rxq_stats)); + + for (i = 0; i < SPNIC_RXQ_XSTATS_NUM; i++) { + xstats[count].value = + *(uint64_t *)(((char *)&rxq_stats) + + spnic_rxq_stats_strings[i].offset); + xstats[count].id = count; + count++; + } + } + + /* Get stats from txq stats structure */ + for (qid = 0; qid < nic_dev->num_sqs; qid++) { + txq = nic_dev->txqs[qid]; + memcpy(&txq_stats, &txq->txq_stats, sizeof(txq->txq_stats)); + + for (i = 0; i < SPNIC_TXQ_XSTATS_NUM; i++) { + xstats[count].value = + *(uint64_t *)(((char *)&txq_stats) + + spnic_txq_stats_strings[i].offset); + xstats[count].id = count; + count++; + } + } + + /* Get stats from vport stats structure */ + err = spnic_get_vport_stats(nic_dev->hwdev, &vport_stats); + if (err) + return err; + + for (i = 0; i < SPNIC_VPORT_XSTATS_NUM; i++) { + xstats[count].value = + *(uint64_t *)(((char *)&vport_stats) + + spnic_vport_stats_strings[i].offset); + xstats[count].id = count; + count++; + } + + if (SPNIC_IS_VF(nic_dev->hwdev)) + return count; + + /* Get stats from phy port stats structure */ + err = spnic_get_phy_port_stats(nic_dev->hwdev, &port_stats); + if (err) + return err; + + for (i = 0; i < SPNIC_PHYPORT_XSTATS_NUM; i++) { + xstats[count].value = *(uint64_t *)(((char *)&port_stats) + + spnic_phyport_stats_strings[i].offset); + xstats[count].id = count; + count++; + } + + return count; +} + +/** + * Clear device extended statistics. + * + * @param[in] dev + * Pointer to ethernet device structure. + * + * @retval zero: Success + * @retval non-zero: Failure + */ +static int spnic_dev_xstats_reset(struct rte_eth_dev *dev) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int err; + + err = spnic_dev_stats_reset(dev); + if (err) + return err; + + if (spnic_func_type(nic_dev->hwdev) != TYPE_VF) { + err = spnic_clear_phy_port_stats(nic_dev->hwdev); + if (err) + return err; + } + + return 0; +} + +/** + * Retrieve names of extended device statistics + * + * @param[in] dev + * Pointer to ethernet device structure. + * @param[out] xstats_names + * Buffer to insert names into. + * + * @return + * Number of xstats names. + */ +static int spnic_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned int limit) +{ + struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int count = 0; + u16 i, q_num; + + if (xstats_names == NULL) + return spnic_xstats_calc_num(nic_dev); + + /* Get pmd rxq stats name */ + for (q_num = 0; q_num < nic_dev->num_rqs; q_num++) { + for (i = 0; i < SPNIC_RXQ_XSTATS_NUM; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "rxq%d_%s_pmd", q_num, + spnic_rxq_stats_strings[i].name); + count++; + } + } + + /* Get pmd txq stats name */ + for (q_num = 0; q_num < nic_dev->num_sqs; q_num++) { + for (i = 0; i < SPNIC_TXQ_XSTATS_NUM; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "txq%d_%s_pmd", q_num, + spnic_txq_stats_strings[i].name); + count++; + } + } + + /* Get vport stats name */ + for (i = 0; i < SPNIC_VPORT_XSTATS_NUM; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", spnic_vport_stats_strings[i].name); + count++; + } + + if (SPNIC_IS_VF(nic_dev->hwdev)) + return count; + + /* Get phy port stats name */ + for (i = 0; i < SPNIC_PHYPORT_XSTATS_NUM; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", spnic_phyport_stats_strings[i].name); + count++; + } + + return count; +} + static void spnic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_rxq_info *rxq_info) { @@ -2063,6 +2527,11 @@ static const struct eth_dev_ops spnic_pmd_ops = { .rss_hash_conf_get = spnic_rss_conf_get, .reta_update = spnic_rss_reta_update, .reta_query = spnic_rss_reta_query, + .stats_get = spnic_dev_stats_get, + .stats_reset = spnic_dev_stats_reset, + .xstats_get = spnic_dev_xstats_get, + .xstats_reset = spnic_dev_xstats_reset, + .xstats_get_names = spnic_dev_xstats_get_names, .rxq_info_get = spnic_rxq_info_get, .txq_info_get = spnic_txq_info_get, .mac_addr_set = spnic_set_mac_addr, @@ -2092,6 +2561,11 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = { .rss_hash_conf_get = spnic_rss_conf_get, .reta_update = spnic_rss_reta_update, .reta_query = spnic_rss_reta_query, + .stats_get = spnic_dev_stats_get, + .stats_reset = spnic_dev_stats_reset, + .xstats_get = spnic_dev_xstats_get, + .xstats_reset = spnic_dev_xstats_reset, + .xstats_get_names = spnic_dev_xstats_get_names, .rxq_info_get = spnic_rxq_info_get, .txq_info_get = spnic_txq_info_get, .mac_addr_set = spnic_set_mac_addr,