Add support for MAC/pause/RMON stats. This enables reporting hardware
statistics in a common way via:

ethtool -S eth0 --all-groups
and
ethtool --include-statistics --show-pause eth0

While doing so, add support for one new stat, receive length error
(RLEC), which is extremely unlikely to happen since most L2 frames have
a type/length field specifying a "type", and raw ethernet frames aren't
used much any longer.

NOTE: I didn't implement Ctrl aka control frame stats because the
hardware doesn't seem to implement support.

Reviewed-by: Marcin Szycik <marcin.szy...@linux.intel.co
Reviewed-by: Jacob Keller <jacob.e.kel...@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeb...@intel.com>
---
Example output:

Standard stats for ens785f1np1:
eth-mac-FramesTransmittedOK: 296
eth-mac-FramesReceivedOK: 339
eth-mac-FrameCheckSequenceErrors: 0
eth-mac-OctetsTransmittedOK: 70410
eth-mac-OctetsReceivedOK: 51414
eth-mac-MulticastFramesXmittedOK: 124
eth-mac-BroadcastFramesXmittedOK: 1
eth-mac-MulticastFramesReceivedOK: 164
eth-mac-BroadcastFramesReceivedOK: 3
eth-mac-InRangeLengthErrors: 0
eth-mac-FrameTooLongErrors: 0
rmon-etherStatsUndersizePkts: 0
rmon-etherStatsOversizePkts: 0
rmon-etherStatsFragments: 0
rmon-etherStatsJabbers: 0
rx-rmon-etherStatsPkts64Octets: 31
rx-rmon-etherStatsPkts65to127Octets: 265
rx-rmon-etherStatsPkts128to255Octets: 26
rx-rmon-etherStatsPkts256to511Octets: 7
rx-rmon-etherStatsPkts512to1023Octets: 1
rx-rmon-etherStatsPkts1024to1522Octets: 6
rx-rmon-etherStatsPkts1523to9522Octets: 3
tx-rmon-etherStatsPkts64Octets: 25
tx-rmon-etherStatsPkts65to127Octets: 255
tx-rmon-etherStatsPkts128to255Octets: 1
tx-rmon-etherStatsPkts256to511Octets: 2
tx-rmon-etherStatsPkts512to1023Octets: 1
tx-rmon-etherStatsPkts1024to1522Octets: 1
tx-rmon-etherStatsPkts1523to9522Octets: 11
and
Pause parameters for ens785f0np0:
Autonegotiate:  on
RX:             off
TX:             off
RX negotiated: off
TX negotiated: off
Statistics:
  tx_pause_frames: 0
  rx_pause_frames: 0
---
 drivers/net/ethernet/intel/ice/ice_ethtool.c | 78 ++++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_main.c    |  3 +
 drivers/net/ethernet/intel/ice/ice_type.h    |  1 +
 3 files changed, 82 insertions(+)

diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c 
b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 62c8205fceba..6f0a857f55c9 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -4282,6 +4282,81 @@ ice_get_module_eeprom(struct net_device *netdev,
        return 0;
 }
 
+static void ice_get_eth_mac_stats(struct net_device *netdev,
+                                 struct ethtool_eth_mac_stats *mac_stats)
+{
+       struct ice_pf *pf = ice_netdev_to_pf(netdev);
+       struct ice_hw_port_stats *ps = &pf->stats;
+
+       mac_stats->FramesTransmittedOK = ps->eth.tx_unicast +
+                                        ps->eth.tx_multicast +
+                                        ps->eth.tx_broadcast;
+       mac_stats->FramesReceivedOK = ps->eth.rx_unicast +
+                                     ps->eth.rx_multicast +
+                                     ps->eth.rx_broadcast;
+       mac_stats->FrameCheckSequenceErrors = ps->crc_errors;
+       mac_stats->OctetsTransmittedOK = ps->eth.tx_bytes;
+       mac_stats->OctetsReceivedOK = ps->eth.rx_bytes;
+       mac_stats->MulticastFramesXmittedOK = ps->eth.tx_multicast;
+       mac_stats->BroadcastFramesXmittedOK = ps->eth.tx_broadcast;
+       mac_stats->MulticastFramesReceivedOK = ps->eth.rx_multicast;
+       mac_stats->BroadcastFramesReceivedOK = ps->eth.rx_broadcast;
+       mac_stats->InRangeLengthErrors = ps->rx_len_errors;
+       mac_stats->FrameTooLongErrors = ps->rx_oversize;
+}
+
+static void ice_get_pause_stats(struct net_device *netdev,
+                               struct ethtool_pause_stats *pause_stats)
+{
+       struct ice_pf *pf = ice_netdev_to_pf(netdev);
+       struct ice_hw_port_stats *ps = &pf->stats;
+
+       pause_stats->tx_pause_frames = ps->link_xon_tx + ps->link_xoff_tx;
+       pause_stats->rx_pause_frames = ps->link_xon_rx + ps->link_xoff_rx;
+}
+
+static const struct ethtool_rmon_hist_range ice_rmon_ranges[] = {
+       {    0,    64 },
+       {   65,   127 },
+       {  128,   255 },
+       {  256,   511 },
+       {  512,  1023 },
+       { 1024,  1522 },
+       { 1523,  9522 },
+       {}
+};
+
+static void ice_get_rmon_stats(struct net_device *netdev,
+                              struct ethtool_rmon_stats *rmon,
+                              const struct ethtool_rmon_hist_range **ranges)
+{
+       struct ice_pf *pf = ice_netdev_to_pf(netdev);
+       struct ice_hw_port_stats *ps = &pf->stats;
+
+       rmon->undersize_pkts    = ps->rx_undersize;
+       rmon->oversize_pkts     = ps->rx_oversize;
+       rmon->fragments         = ps->rx_fragments;
+       rmon->jabbers           = ps->rx_jabber;
+
+       rmon->hist[0]           = ps->rx_size_64;
+       rmon->hist[1]           = ps->rx_size_127;
+       rmon->hist[2]           = ps->rx_size_255;
+       rmon->hist[3]           = ps->rx_size_511;
+       rmon->hist[4]           = ps->rx_size_1023;
+       rmon->hist[5]           = ps->rx_size_1522;
+       rmon->hist[6]           = ps->rx_size_big;
+
+       rmon->hist_tx[0]        = ps->tx_size_64;
+       rmon->hist_tx[1]        = ps->tx_size_127;
+       rmon->hist_tx[2]        = ps->tx_size_255;
+       rmon->hist_tx[3]        = ps->tx_size_511;
+       rmon->hist_tx[4]        = ps->tx_size_1023;
+       rmon->hist_tx[5]        = ps->tx_size_1522;
+       rmon->hist_tx[6]        = ps->tx_size_big;
+
+       *ranges = ice_rmon_ranges;
+}
+
 static const struct ethtool_ops ice_ethtool_ops = {
        .cap_rss_ctx_supported  = true,
        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
@@ -4329,6 +4404,9 @@ static const struct ethtool_ops ice_ethtool_ops = {
        .set_fecparam           = ice_set_fecparam,
        .get_module_info        = ice_get_module_info,
        .get_module_eeprom      = ice_get_module_eeprom,
+       .get_eth_mac_stats      = ice_get_eth_mac_stats,
+       .get_pause_stats        = ice_get_pause_stats,
+       .get_rmon_stats         = ice_get_rmon_stats,
 };
 
 static const struct ethtool_ops ice_ethtool_safe_mode_ops = {
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c 
b/drivers/net/ethernet/intel/ice/ice_main.c
index f60c022f7960..4db3a6056f41 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -7034,6 +7034,9 @@ void ice_update_pf_stats(struct ice_pf *pf)
                          &prev_ps->mac_remote_faults,
                          &cur_ps->mac_remote_faults);
 
+       ice_stat_update32(hw, GLPRT_RLEC(port), pf->stat_prev_loaded,
+                         &prev_ps->rx_len_errors, &cur_ps->rx_len_errors);
+
        ice_stat_update32(hw, GLPRT_RUC(port), pf->stat_prev_loaded,
                          &prev_ps->rx_undersize, &cur_ps->rx_undersize);
 
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h 
b/drivers/net/ethernet/intel/ice/ice_type.h
index f0796a93f428..b156d01196e2 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -1007,6 +1007,7 @@ struct ice_hw_port_stats {
        u64 error_bytes;                /* errbc */
        u64 mac_local_faults;           /* mlfc */
        u64 mac_remote_faults;          /* mrfc */
+       u64 rx_len_errors;              /* rlec */
        u64 link_xon_rx;                /* lxonrxc */
        u64 link_xoff_rx;               /* lxoffrxc */
        u64 link_xon_tx;                /* lxontxc */
-- 
2.43.0

Reply via email to