162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/ethtool.h> 562306a36Sopenharmony_ci#include <linux/kernel.h> 662306a36Sopenharmony_ci#include <linux/mutex.h> 762306a36Sopenharmony_ci#include <linux/netdevice.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "ionic.h" 1062306a36Sopenharmony_ci#include "ionic_lif.h" 1162306a36Sopenharmony_ci#include "ionic_stats.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic const struct ionic_stat_desc ionic_lif_stats_desc[] = { 1462306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_packets), 1562306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_bytes), 1662306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(rx_packets), 1762306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(rx_bytes), 1862306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_tso), 1962306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_tso_bytes), 2062306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_csum_none), 2162306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(tx_csum), 2262306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(rx_csum_none), 2362306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(rx_csum_complete), 2462306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(rx_csum_error), 2562306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(hw_tx_dropped), 2662306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(hw_rx_dropped), 2762306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(hw_rx_over_errors), 2862306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(hw_rx_missed_errors), 2962306a36Sopenharmony_ci IONIC_LIF_STAT_DESC(hw_tx_aborted_errors), 3062306a36Sopenharmony_ci}; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic const struct ionic_stat_desc ionic_port_stats_desc[] = { 3362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_ok), 3462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_all), 3562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_bad_fcs), 3662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_bad_all), 3762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(octets_rx_ok), 3862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(octets_rx_all), 3962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_unicast), 4062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_multicast), 4162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_broadcast), 4262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pause), 4362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_bad_length), 4462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_undersized), 4562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_oversized), 4662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_fragments), 4762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_jabber), 4862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pripause), 4962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_stomped_crc), 5062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_too_long), 5162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_vlan_good), 5262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_dropped), 5362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_less_than_64b), 5462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_64b), 5562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_65b_127b), 5662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_128b_255b), 5762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_256b_511b), 5862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_512b_1023b), 5962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_1024b_1518b), 6062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_1519b_2047b), 6162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_2048b_4095b), 6262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_4096b_8191b), 6362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_8192b_9215b), 6462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_other), 6562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_ok), 6662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_all), 6762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_bad), 6862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(octets_tx_ok), 6962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(octets_tx_total), 7062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_unicast), 7162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_multicast), 7262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_broadcast), 7362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pause), 7462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pripause), 7562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_vlan), 7662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_less_than_64b), 7762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_64b), 7862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_65b_127b), 7962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_128b_255b), 8062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_256b_511b), 8162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_512b_1023b), 8262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_1024b_1518b), 8362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_1519b_2047b), 8462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_2048b_4095b), 8562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_4096b_8191b), 8662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_8192b_9215b), 8762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_other), 8862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_0), 8962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_1), 9062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_2), 9162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_3), 9262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_4), 9362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_5), 9462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_6), 9562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_pri_7), 9662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_0), 9762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_1), 9862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_2), 9962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_3), 10062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_4), 10162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_5), 10262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_6), 10362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_rx_pri_7), 10462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_0_1us_count), 10562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_1_1us_count), 10662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_2_1us_count), 10762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_3_1us_count), 10862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_4_1us_count), 10962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_5_1us_count), 11062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_6_1us_count), 11162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(tx_pripause_7_1us_count), 11262306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_0_1us_count), 11362306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_1_1us_count), 11462306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_2_1us_count), 11562306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_3_1us_count), 11662306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_4_1us_count), 11762306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_5_1us_count), 11862306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_6_1us_count), 11962306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pripause_7_1us_count), 12062306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(rx_pause_1us_count), 12162306a36Sopenharmony_ci IONIC_PORT_STAT_DESC(frames_tx_truncated), 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic const struct ionic_stat_desc ionic_tx_stats_desc[] = { 12562306a36Sopenharmony_ci IONIC_TX_STAT_DESC(pkts), 12662306a36Sopenharmony_ci IONIC_TX_STAT_DESC(bytes), 12762306a36Sopenharmony_ci IONIC_TX_STAT_DESC(clean), 12862306a36Sopenharmony_ci IONIC_TX_STAT_DESC(dma_map_err), 12962306a36Sopenharmony_ci IONIC_TX_STAT_DESC(linearize), 13062306a36Sopenharmony_ci IONIC_TX_STAT_DESC(frags), 13162306a36Sopenharmony_ci IONIC_TX_STAT_DESC(tso), 13262306a36Sopenharmony_ci IONIC_TX_STAT_DESC(tso_bytes), 13362306a36Sopenharmony_ci IONIC_TX_STAT_DESC(hwstamp_valid), 13462306a36Sopenharmony_ci IONIC_TX_STAT_DESC(hwstamp_invalid), 13562306a36Sopenharmony_ci IONIC_TX_STAT_DESC(csum_none), 13662306a36Sopenharmony_ci IONIC_TX_STAT_DESC(csum), 13762306a36Sopenharmony_ci IONIC_TX_STAT_DESC(vlan_inserted), 13862306a36Sopenharmony_ci}; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic const struct ionic_stat_desc ionic_rx_stats_desc[] = { 14162306a36Sopenharmony_ci IONIC_RX_STAT_DESC(pkts), 14262306a36Sopenharmony_ci IONIC_RX_STAT_DESC(bytes), 14362306a36Sopenharmony_ci IONIC_RX_STAT_DESC(dma_map_err), 14462306a36Sopenharmony_ci IONIC_RX_STAT_DESC(alloc_err), 14562306a36Sopenharmony_ci IONIC_RX_STAT_DESC(csum_none), 14662306a36Sopenharmony_ci IONIC_RX_STAT_DESC(csum_complete), 14762306a36Sopenharmony_ci IONIC_RX_STAT_DESC(csum_error), 14862306a36Sopenharmony_ci IONIC_RX_STAT_DESC(hwstamp_valid), 14962306a36Sopenharmony_ci IONIC_RX_STAT_DESC(hwstamp_invalid), 15062306a36Sopenharmony_ci IONIC_RX_STAT_DESC(dropped), 15162306a36Sopenharmony_ci IONIC_RX_STAT_DESC(vlan_stripped), 15262306a36Sopenharmony_ci}; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#define IONIC_NUM_LIF_STATS ARRAY_SIZE(ionic_lif_stats_desc) 15562306a36Sopenharmony_ci#define IONIC_NUM_PORT_STATS ARRAY_SIZE(ionic_port_stats_desc) 15662306a36Sopenharmony_ci#define IONIC_NUM_TX_STATS ARRAY_SIZE(ionic_tx_stats_desc) 15762306a36Sopenharmony_ci#define IONIC_NUM_RX_STATS ARRAY_SIZE(ionic_rx_stats_desc) 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci#define MAX_Q(lif) ((lif)->netdev->real_num_tx_queues) 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic void ionic_add_lif_txq_stats(struct ionic_lif *lif, int q_num, 16262306a36Sopenharmony_ci struct ionic_lif_sw_stats *stats) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci struct ionic_tx_stats *txstats = &lif->txqstats[q_num]; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci stats->tx_packets += txstats->pkts; 16762306a36Sopenharmony_ci stats->tx_bytes += txstats->bytes; 16862306a36Sopenharmony_ci stats->tx_tso += txstats->tso; 16962306a36Sopenharmony_ci stats->tx_tso_bytes += txstats->tso_bytes; 17062306a36Sopenharmony_ci stats->tx_csum_none += txstats->csum_none; 17162306a36Sopenharmony_ci stats->tx_csum += txstats->csum; 17262306a36Sopenharmony_ci stats->tx_hwstamp_valid += txstats->hwstamp_valid; 17362306a36Sopenharmony_ci stats->tx_hwstamp_invalid += txstats->hwstamp_invalid; 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num, 17762306a36Sopenharmony_ci struct ionic_lif_sw_stats *stats) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci struct ionic_rx_stats *rxstats = &lif->rxqstats[q_num]; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci stats->rx_packets += rxstats->pkts; 18262306a36Sopenharmony_ci stats->rx_bytes += rxstats->bytes; 18362306a36Sopenharmony_ci stats->rx_csum_none += rxstats->csum_none; 18462306a36Sopenharmony_ci stats->rx_csum_complete += rxstats->csum_complete; 18562306a36Sopenharmony_ci stats->rx_csum_error += rxstats->csum_error; 18662306a36Sopenharmony_ci stats->rx_hwstamp_valid += rxstats->hwstamp_valid; 18762306a36Sopenharmony_ci stats->rx_hwstamp_invalid += rxstats->hwstamp_invalid; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic void ionic_get_lif_stats(struct ionic_lif *lif, 19162306a36Sopenharmony_ci struct ionic_lif_sw_stats *stats) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci struct rtnl_link_stats64 ns; 19462306a36Sopenharmony_ci int q_num; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci memset(stats, 0, sizeof(*stats)); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci for (q_num = 0; q_num < MAX_Q(lif); q_num++) { 19962306a36Sopenharmony_ci ionic_add_lif_txq_stats(lif, q_num, stats); 20062306a36Sopenharmony_ci ionic_add_lif_rxq_stats(lif, q_num, stats); 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci if (lif->hwstamp_txq) 20462306a36Sopenharmony_ci ionic_add_lif_txq_stats(lif, lif->hwstamp_txq->q.index, stats); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci if (lif->hwstamp_rxq) 20762306a36Sopenharmony_ci ionic_add_lif_rxq_stats(lif, lif->hwstamp_rxq->q.index, stats); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci ionic_get_stats64(lif->netdev, &ns); 21062306a36Sopenharmony_ci stats->hw_tx_dropped = ns.tx_dropped; 21162306a36Sopenharmony_ci stats->hw_rx_dropped = ns.rx_dropped; 21262306a36Sopenharmony_ci stats->hw_rx_over_errors = ns.rx_over_errors; 21362306a36Sopenharmony_ci stats->hw_rx_missed_errors = ns.rx_missed_errors; 21462306a36Sopenharmony_ci stats->hw_tx_aborted_errors = ns.tx_aborted_errors; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic u64 ionic_sw_stats_get_count(struct ionic_lif *lif) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci u64 total = 0, tx_queues = MAX_Q(lif), rx_queues = MAX_Q(lif); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci if (lif->hwstamp_txq) 22262306a36Sopenharmony_ci tx_queues += 1; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci if (lif->hwstamp_rxq) 22562306a36Sopenharmony_ci rx_queues += 1; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci total += IONIC_NUM_LIF_STATS; 22862306a36Sopenharmony_ci total += IONIC_NUM_PORT_STATS; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci total += tx_queues * IONIC_NUM_TX_STATS; 23162306a36Sopenharmony_ci total += rx_queues * IONIC_NUM_RX_STATS; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return total; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic void ionic_sw_stats_get_tx_strings(struct ionic_lif *lif, u8 **buf, 23762306a36Sopenharmony_ci int q_num) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci int i; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_TX_STATS; i++) 24262306a36Sopenharmony_ci ethtool_sprintf(buf, "tx_%d_%s", q_num, 24362306a36Sopenharmony_ci ionic_tx_stats_desc[i].name); 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic void ionic_sw_stats_get_rx_strings(struct ionic_lif *lif, u8 **buf, 24762306a36Sopenharmony_ci int q_num) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci int i; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_RX_STATS; i++) 25262306a36Sopenharmony_ci ethtool_sprintf(buf, "rx_%d_%s", q_num, 25362306a36Sopenharmony_ci ionic_rx_stats_desc[i].name); 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cistatic void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci int i, q_num; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_LIF_STATS; i++) 26162306a36Sopenharmony_ci ethtool_sprintf(buf, ionic_lif_stats_desc[i].name); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_PORT_STATS; i++) 26462306a36Sopenharmony_ci ethtool_sprintf(buf, ionic_port_stats_desc[i].name); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci for (q_num = 0; q_num < MAX_Q(lif); q_num++) 26762306a36Sopenharmony_ci ionic_sw_stats_get_tx_strings(lif, buf, q_num); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci if (lif->hwstamp_txq) 27062306a36Sopenharmony_ci ionic_sw_stats_get_tx_strings(lif, buf, lif->hwstamp_txq->q.index); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci for (q_num = 0; q_num < MAX_Q(lif); q_num++) 27362306a36Sopenharmony_ci ionic_sw_stats_get_rx_strings(lif, buf, q_num); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci if (lif->hwstamp_rxq) 27662306a36Sopenharmony_ci ionic_sw_stats_get_rx_strings(lif, buf, lif->hwstamp_rxq->q.index); 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic void ionic_sw_stats_get_txq_values(struct ionic_lif *lif, u64 **buf, 28062306a36Sopenharmony_ci int q_num) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci struct ionic_tx_stats *txstats; 28362306a36Sopenharmony_ci int i; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci txstats = &lif->txqstats[q_num]; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_TX_STATS; i++) { 28862306a36Sopenharmony_ci **buf = IONIC_READ_STAT64(txstats, &ionic_tx_stats_desc[i]); 28962306a36Sopenharmony_ci (*buf)++; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic void ionic_sw_stats_get_rxq_values(struct ionic_lif *lif, u64 **buf, 29462306a36Sopenharmony_ci int q_num) 29562306a36Sopenharmony_ci{ 29662306a36Sopenharmony_ci struct ionic_rx_stats *rxstats; 29762306a36Sopenharmony_ci int i; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci rxstats = &lif->rxqstats[q_num]; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_RX_STATS; i++) { 30262306a36Sopenharmony_ci **buf = IONIC_READ_STAT64(rxstats, &ionic_rx_stats_desc[i]); 30362306a36Sopenharmony_ci (*buf)++; 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct ionic_port_stats *port_stats; 31062306a36Sopenharmony_ci struct ionic_lif_sw_stats lif_stats; 31162306a36Sopenharmony_ci int i, q_num; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci ionic_get_lif_stats(lif, &lif_stats); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_LIF_STATS; i++) { 31662306a36Sopenharmony_ci **buf = IONIC_READ_STAT64(&lif_stats, &ionic_lif_stats_desc[i]); 31762306a36Sopenharmony_ci (*buf)++; 31862306a36Sopenharmony_ci } 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci port_stats = &lif->ionic->idev.port_info->stats; 32162306a36Sopenharmony_ci for (i = 0; i < IONIC_NUM_PORT_STATS; i++) { 32262306a36Sopenharmony_ci **buf = IONIC_READ_STAT_LE64(port_stats, 32362306a36Sopenharmony_ci &ionic_port_stats_desc[i]); 32462306a36Sopenharmony_ci (*buf)++; 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci for (q_num = 0; q_num < MAX_Q(lif); q_num++) 32862306a36Sopenharmony_ci ionic_sw_stats_get_txq_values(lif, buf, q_num); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci if (lif->hwstamp_txq) 33162306a36Sopenharmony_ci ionic_sw_stats_get_txq_values(lif, buf, lif->hwstamp_txq->q.index); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci for (q_num = 0; q_num < MAX_Q(lif); q_num++) 33462306a36Sopenharmony_ci ionic_sw_stats_get_rxq_values(lif, buf, q_num); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci if (lif->hwstamp_rxq) 33762306a36Sopenharmony_ci ionic_sw_stats_get_rxq_values(lif, buf, lif->hwstamp_rxq->q.index); 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ciconst struct ionic_stats_group_intf ionic_stats_groups[] = { 34162306a36Sopenharmony_ci /* SW Stats group */ 34262306a36Sopenharmony_ci { 34362306a36Sopenharmony_ci .get_strings = ionic_sw_stats_get_strings, 34462306a36Sopenharmony_ci .get_values = ionic_sw_stats_get_values, 34562306a36Sopenharmony_ci .get_count = ionic_sw_stats_get_count, 34662306a36Sopenharmony_ci }, 34762306a36Sopenharmony_ci /* Add more stat groups here */ 34862306a36Sopenharmony_ci}; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ciconst int ionic_num_stats_grps = ARRAY_SIZE(ionic_stats_groups); 351