diff options
author | Vijayakannan Ayyathurai <vijayakannan.ayyathurai@intel.com> | 2021-08-16 09:15:59 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-08-16 13:36:04 +0300 |
commit | 68e9c5dee1cf9f5651a894a151d72b7fc21172d3 (patch) | |
tree | 53eb734136812d008517ffdffef60bbfe387ec9b /drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |
parent | 1975df880b959e30f28d66148a12d77b458abd76 (diff) | |
download | linux-68e9c5dee1cf9f5651a894a151d72b7fc21172d3.tar.xz |
net: stmmac: add ethtool per-queue statistic framework
Adding generic ethtool per-queue statistic framework to display the
statistics for each rx/tx queue. In future, users can avail it to add
more per-queue specific counters. Number of rx/tx queues displayed is
depending on the available rx/tx queues in that particular MAC config
and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined
in the driver.
Ethtool per-queue statistic display will look like below, when users
start adding more counters.
Example:
q0_tx_statA:
q0_tx_statB:
q0_tx_statC:
|
q0_tx_statX:
.
.
.
qMAX_tx_statA:
qMAX_tx_statB:
qMAX_tx_statC:
|
qMAX_tx_statX:
q0_rx_statA:
q0_rx_statB:
q0_rx_statC:
|
q0_rx_statX:
.
.
.
qMAX_rx_statA:
qMAX_rx_statB:
qMAX_rx_statC:
|
qMAX_rx_statX:
In addition, this patch has the support on displaying the number of
packets received and transmitted per queue.
Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index d0ce608b81c3..10c0895d0b43 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -261,6 +261,16 @@ static const struct stmmac_stats stmmac_mmc[] = { }; #define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc) +static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = { + "tx_pkt_n", +#define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string) +}; + +static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = { + "rx_pkt_n", +#define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string) +}; + static void stmmac_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -510,6 +520,31 @@ stmmac_set_pauseparam(struct net_device *netdev, } } +static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) +{ + u32 tx_cnt = priv->plat->tx_queues_to_use; + u32 rx_cnt = priv->plat->rx_queues_to_use; + int q, stat; + char *p; + + for (q = 0; q < tx_cnt; q++) { + p = (char *)priv + offsetof(struct stmmac_priv, + xstats.txq_stats[q].tx_pkt_n); + for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { + *data++ = (*(u64 *)p); + p += sizeof(u64 *); + } + } + for (q = 0; q < rx_cnt; q++) { + p = (char *)priv + offsetof(struct stmmac_priv, + xstats.rxq_stats[q].rx_pkt_n); + for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { + *data++ = (*(u64 *)p); + p += sizeof(u64 *); + } + } +} + static void stmmac_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 *data) { @@ -560,16 +595,21 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, data[j++] = (stmmac_gstrings_stats[i].sizeof_stat == sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p); } + stmmac_get_per_qstats(priv, &data[j]); } static int stmmac_get_sset_count(struct net_device *netdev, int sset) { struct stmmac_priv *priv = netdev_priv(netdev); + u32 tx_cnt = priv->plat->tx_queues_to_use; + u32 rx_cnt = priv->plat->rx_queues_to_use; int i, len, safety_len = 0; switch (sset) { case ETH_SS_STATS: - len = STMMAC_STATS_LEN; + len = STMMAC_STATS_LEN + + STMMAC_TXQ_STATS * tx_cnt + + STMMAC_RXQ_STATS * rx_cnt; if (priv->dma_cap.rmon) len += STMMAC_MMC_STATS_LEN; @@ -592,6 +632,28 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset) } } +static void stmmac_get_qstats_string(struct stmmac_priv *priv, u8 *data) +{ + u32 tx_cnt = priv->plat->tx_queues_to_use; + u32 rx_cnt = priv->plat->rx_queues_to_use; + int q, stat; + + for (q = 0; q < tx_cnt; q++) { + for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { + snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q, + stmmac_qstats_tx_string[stat]); + data += ETH_GSTRING_LEN; + } + } + for (q = 0; q < rx_cnt; q++) { + for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { + snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q, + stmmac_qstats_rx_string[stat]); + data += ETH_GSTRING_LEN; + } + } +} + static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data) { int i; @@ -622,6 +684,7 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data) ETH_GSTRING_LEN); p += ETH_GSTRING_LEN; } + stmmac_get_qstats_string(priv, p); break; case ETH_SS_TEST: stmmac_selftest_get_strings(priv, p); |