diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/enetc/enetc_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 79 |
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 | \ |