bnxt_en: show only relevant ethtool stats for a TX or RX ring

Currently, ethtool -S shows all TX/RX ring counters whether the
channel is combined, RX, or TX.  The unused counters will always be
zero.  Improve it by showing only the relevant counters if the channel
is RX or TX.  If the channel is combined, the counters will be shown
exactly the same as before.

[ MChan: Lots of cleanups and simplifications on Rajesh's original
code]

Signed-off-by: Rajesh Ravi <rajesh.ravi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Rajesh Ravi 2020-05-04 04:50:41 -04:00 committed by David S. Miller
parent 3316d50905
commit 125592fbf4

View file

@ -494,12 +494,20 @@ static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp)
static int bnxt_get_num_ring_stats(struct bnxt *bp)
{
int rx, tx, cmn;
bool sh = false;
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
sh = true;
rx = NUM_RING_RX_HW_STATS + NUM_RING_RX_SW_STATS +
bnxt_get_num_tpa_ring_stats(bp);
tx = NUM_RING_TX_HW_STATS;
cmn = NUM_RING_CMN_SW_STATS;
return (rx + tx + cmn) * bp->cp_nr_rings;
if (sh)
return (rx + tx + cmn) * bp->cp_nr_rings;
else
return rx * bp->rx_nr_rings + tx * bp->tx_nr_rings +
cmn * bp->cp_nr_rings;
}
static int bnxt_get_num_stats(struct bnxt *bp)
@ -540,13 +548,29 @@ static int bnxt_get_sset_count(struct net_device *dev, int sset)
}
}
static bool is_rx_ring(struct bnxt *bp, int ring_num)
{
return ring_num < bp->rx_nr_rings;
}
static bool is_tx_ring(struct bnxt *bp, int ring_num)
{
int tx_base = 0;
if (!(bp->flags & BNXT_FLAG_SHARED_RINGS))
tx_base = bp->rx_nr_rings;
if (ring_num >= tx_base && ring_num < (tx_base + bp->tx_nr_rings))
return true;
return false;
}
static void bnxt_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *buf)
{
u32 i, j = 0;
struct bnxt *bp = netdev_priv(dev);
u32 stat_fields = NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS +
bnxt_get_num_tpa_ring_stats(bp);
u32 tpa_stats;
if (!bp->bnapi) {
j += bnxt_get_num_ring_stats(bp) + BNXT_NUM_SW_FUNC_STATS;
@ -556,6 +580,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++)
bnxt_sw_func_stats[i].counter = 0;
tpa_stats = bnxt_get_num_tpa_ring_stats(bp);
for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
@ -563,12 +588,30 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
u64 *sw;
int k;
for (k = 0; k < stat_fields; j++, k++)
if (is_rx_ring(bp, i)) {
for (k = 0; k < NUM_RING_RX_HW_STATS; j++, k++)
buf[j] = le64_to_cpu(hw_stats[k]);
}
if (is_tx_ring(bp, i)) {
k = NUM_RING_RX_HW_STATS;
for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
j++, k++)
buf[j] = le64_to_cpu(hw_stats[k]);
}
if (!tpa_stats || !is_rx_ring(bp, i))
goto skip_tpa_ring_stats;
k = NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS +
tpa_stats; j++, k++)
buf[j] = le64_to_cpu(hw_stats[k]);
skip_tpa_ring_stats:
sw = (u64 *)&cpr->sw_stats.rx;
for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++)
buf[j] = sw[k];
if (is_rx_ring(bp, i)) {
for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++)
buf[j] = sw[k];
}
sw = (u64 *)&cpr->sw_stats.cmn;
for (k = 0; k < NUM_RING_CMN_SW_STATS; j++, k++)
@ -650,20 +693,24 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < bp->cp_nr_rings; i++) {
num_str = NUM_RING_RX_HW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_ring_rx_stats_str[j]);
buf += ETH_GSTRING_LEN;
if (is_rx_ring(bp, i)) {
num_str = NUM_RING_RX_HW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_ring_rx_stats_str[j]);
buf += ETH_GSTRING_LEN;
}
}
num_str = NUM_RING_TX_HW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_ring_tx_stats_str[j]);
buf += ETH_GSTRING_LEN;
if (is_tx_ring(bp, i)) {
num_str = NUM_RING_TX_HW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_ring_tx_stats_str[j]);
buf += ETH_GSTRING_LEN;
}
}
num_str = bnxt_get_num_tpa_ring_stats(bp);
if (!num_str)
if (!num_str || !is_rx_ring(bp, i))
goto skip_tpa_stats;
if (bp->max_tpa_v2)
@ -676,11 +723,13 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
buf += ETH_GSTRING_LEN;
}
skip_tpa_stats:
num_str = NUM_RING_RX_SW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_rx_sw_stats_str[j]);
buf += ETH_GSTRING_LEN;
if (is_rx_ring(bp, i)) {
num_str = NUM_RING_RX_SW_STATS;
for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i,
bnxt_rx_sw_stats_str[j]);
buf += ETH_GSTRING_LEN;
}
}
num_str = NUM_RING_CMN_SW_STATS;
for (j = 0; j < num_str; j++) {