Commit 125592fb authored by Rajesh Ravi's avatar Rajesh Ravi Committed by David S. Miller

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: default avatarRajesh Ravi <rajesh.ravi@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3316d509
...@@ -494,12 +494,20 @@ static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp) ...@@ -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) static int bnxt_get_num_ring_stats(struct bnxt *bp)
{ {
int rx, tx, cmn; 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 + rx = NUM_RING_RX_HW_STATS + NUM_RING_RX_SW_STATS +
bnxt_get_num_tpa_ring_stats(bp); bnxt_get_num_tpa_ring_stats(bp);
tx = NUM_RING_TX_HW_STATS; tx = NUM_RING_TX_HW_STATS;
cmn = NUM_RING_CMN_SW_STATS; cmn = NUM_RING_CMN_SW_STATS;
if (sh)
return (rx + tx + cmn) * bp->cp_nr_rings; 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) 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) ...@@ -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, static void bnxt_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *buf) struct ethtool_stats *stats, u64 *buf)
{ {
u32 i, j = 0; u32 i, j = 0;
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
u32 stat_fields = NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS + u32 tpa_stats;
bnxt_get_num_tpa_ring_stats(bp);
if (!bp->bnapi) { if (!bp->bnapi) {
j += bnxt_get_num_ring_stats(bp) + BNXT_NUM_SW_FUNC_STATS; 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, ...@@ -556,6 +580,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++)
bnxt_sw_func_stats[i].counter = 0; 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++) { for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i]; struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
...@@ -563,12 +588,30 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, ...@@ -563,12 +588,30 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
u64 *sw; u64 *sw;
int k; 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]); buf[j] = le64_to_cpu(hw_stats[k]);
skip_tpa_ring_stats:
sw = (u64 *)&cpr->sw_stats.rx; sw = (u64 *)&cpr->sw_stats.rx;
if (is_rx_ring(bp, i)) {
for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++) for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++)
buf[j] = sw[k]; buf[j] = sw[k];
}
sw = (u64 *)&cpr->sw_stats.cmn; sw = (u64 *)&cpr->sw_stats.cmn;
for (k = 0; k < NUM_RING_CMN_SW_STATS; j++, k++) 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) ...@@ -650,20 +693,24 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
switch (stringset) { switch (stringset) {
case ETH_SS_STATS: case ETH_SS_STATS:
for (i = 0; i < bp->cp_nr_rings; i++) { for (i = 0; i < bp->cp_nr_rings; i++) {
if (is_rx_ring(bp, i)) {
num_str = NUM_RING_RX_HW_STATS; num_str = NUM_RING_RX_HW_STATS;
for (j = 0; j < num_str; j++) { for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i, sprintf(buf, "[%d]: %s", i,
bnxt_ring_rx_stats_str[j]); bnxt_ring_rx_stats_str[j]);
buf += ETH_GSTRING_LEN; buf += ETH_GSTRING_LEN;
} }
}
if (is_tx_ring(bp, i)) {
num_str = NUM_RING_TX_HW_STATS; num_str = NUM_RING_TX_HW_STATS;
for (j = 0; j < num_str; j++) { for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i, sprintf(buf, "[%d]: %s", i,
bnxt_ring_tx_stats_str[j]); bnxt_ring_tx_stats_str[j]);
buf += ETH_GSTRING_LEN; buf += ETH_GSTRING_LEN;
} }
}
num_str = bnxt_get_num_tpa_ring_stats(bp); num_str = bnxt_get_num_tpa_ring_stats(bp);
if (!num_str) if (!num_str || !is_rx_ring(bp, i))
goto skip_tpa_stats; goto skip_tpa_stats;
if (bp->max_tpa_v2) if (bp->max_tpa_v2)
...@@ -676,12 +723,14 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf) ...@@ -676,12 +723,14 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
buf += ETH_GSTRING_LEN; buf += ETH_GSTRING_LEN;
} }
skip_tpa_stats: skip_tpa_stats:
if (is_rx_ring(bp, i)) {
num_str = NUM_RING_RX_SW_STATS; num_str = NUM_RING_RX_SW_STATS;
for (j = 0; j < num_str; j++) { for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i, sprintf(buf, "[%d]: %s", i,
bnxt_rx_sw_stats_str[j]); bnxt_rx_sw_stats_str[j]);
buf += ETH_GSTRING_LEN; buf += ETH_GSTRING_LEN;
} }
}
num_str = NUM_RING_CMN_SW_STATS; num_str = NUM_RING_CMN_SW_STATS;
for (j = 0; j < num_str; j++) { for (j = 0; j < num_str; j++) {
sprintf(buf, "[%d]: %s", i, sprintf(buf, "[%d]: %s", i,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment