summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/enetc/enetc_ethtool.c')
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_ethtool.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index 89121d7ce3e6..9136b31feae0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -187,6 +187,21 @@ static const struct {
{ ENETC_PICDR(3), "ICM DR3 discarded frames" },
};
+static const struct {
+ int reg;
+ char name[ETH_GSTRING_LEN];
+} enetc_pmac_counters[] = {
+ { ENETC_PM1_RFRM, "PMAC rx frames" },
+ { ENETC_PM1_RPKT, "PMAC rx packets" },
+ { ENETC_PM1_RDRP, "PMAC rx dropped packets" },
+ { ENETC_PM1_RFRG, "PMAC rx fragment packets" },
+ { ENETC_PM1_TFRM, "PMAC tx frames" },
+ { ENETC_PM1_TERR, "PMAC tx error frames" },
+ { ENETC_PM1_TPKT, "PMAC tx packets" },
+ { ENETC_MAC_MERGE_MMFCRXR, "MAC merge fragment rx counter" },
+ { ENETC_MAC_MERGE_MMFCTXR, "MAC merge fragment tx counter"},
+};
+
static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
"Rx ring %2d frames",
"Rx ring %2d alloc errors",
@@ -196,18 +211,34 @@ static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
"Tx ring %2d frames",
};
+static const char tx_windrop_stats[][ETH_GSTRING_LEN] = {
+ "Tx window drop %2d frames",
+};
+
static int enetc_get_sset_count(struct net_device *ndev, int sset)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ int len;
+
+ if (sset != ETH_SS_STATS)
+ return -EOPNOTSUPP;
- if (sset == ETH_SS_STATS)
- return ARRAY_SIZE(enetc_si_counters) +
- ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings +
- ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings +
- (enetc_si_is_pf(priv->si) ?
- ARRAY_SIZE(enetc_port_counters) : 0);
+ len = ARRAY_SIZE(enetc_si_counters) +
+ ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings +
+ ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings;
- return -EOPNOTSUPP;
+ if (!enetc_si_is_pf(priv->si))
+ return len;
+
+ len += ARRAY_SIZE(enetc_port_counters);
+
+ if (priv->active_offloads & ENETC_F_QBU)
+ len += ARRAY_SIZE(enetc_pmac_counters);
+
+ if (priv->active_offloads & ENETC_F_QBV)
+ len += ARRAY_SIZE(tx_windrop_stats) * priv->num_tx_rings;
+
+ return len;
}
static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
@@ -245,6 +276,28 @@ static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
+
+ if (!(priv->active_offloads & ENETC_F_QBU))
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++) {
+ strlcpy(p, enetc_pmac_counters[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ if (!((priv->active_offloads & ENETC_F_QBV)))
+ break;
+
+ for (i = 0; i < priv->num_tx_rings; i++) {
+ for (j = 0; j < ARRAY_SIZE(tx_windrop_stats); j++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ tx_windrop_stats[j],
+ i);
+ p += ETH_GSTRING_LEN;
+ }
+ }
+
break;
}
}
@@ -272,6 +325,18 @@ static void enetc_get_ethtool_stats(struct net_device *ndev,
for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
+
+ if (!(priv->active_offloads & ENETC_F_QBU))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++)
+ data[o++] = enetc_port_rd(hw, enetc_pmac_counters[i].reg);
+
+ if (!((priv->active_offloads & ENETC_F_QBV)))
+ return;
+
+ for (i = 0; i < priv->num_tx_rings; i++)
+ data[o++] = priv->tx_ring[i]->stats.win_drop;
}
#define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \