From: Eric Joyner <eric.joyner@amd.com>
To: <netdev@vger.kernel.org>
Cc: Brett Creeley <brett.creeley@amd.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
"Jakub Kicinski" <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
"Nikhil P. Rao" <nikhil.rao@amd.com>,
Eric Joyner <eric.joyner@amd.com>,
Eric Dumazet <edumazet@kernel.org>
Subject: [PATCH net-next v3 5/5] ionic: Add .get_fec_stats ethtool handler
Date: Wed, 4 Nov 2026 13:19:46 -0800 [thread overview]
Message-ID: <20261104-ionic-get-fec-stats-v3-5-b261fd53d0a7@amd.com> (raw)
In-Reply-To: <20261104-ionic-get-fec-stats-v3-0-b261fd53d0a7@amd.com>
Reports FEC statistics totals and an 802.3ck FEC histogram. Per-lane
counts currently aren't supported. Every counter reported here comes
from the RS decoder, including fec_corrected_bits_total despite its
name, and the only histogram format firmware produces is the 16-bin one
from RS(544,514), so nothing is reported unless RS is the active FEC
mode.
These are physical port counters, so virtual functions are skipped the
same way ionic_get_link_ext_stats() skips them, rather than reporting the
port's counters as if they belonged to the VF.
The reporting of these statistics is gated by DEV_CAP_EXTRA_STATS and
checks for IONIC_STAT_INVALID, since only the newest devices support
reporting all of these stats. Older devices can only report some of the
statistics or not at all, and so the output will properly exclude those
unsupported statistics.
The firmware writes these counters by DMA while they are being read.
Use READ_ONCE() to ensure that the IONIC_STAT_INVALID test and the store
see the same value. Counters are still read one at a time, so the set
reported can span more than one firmware update.
Co-developed-by: Nikhil P. Rao <nikhil.rao@amd.com>
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
Signed-off-by: Eric Joyner <eric.joyner@amd.com>
---
.../net/ethernet/pensando/ionic/ionic_ethtool.c | 83 ++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 2e067481bb15..1d32fa811003 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -450,6 +450,88 @@ static int ionic_get_fecparam(struct net_device *netdev,
return 0;
}
+#define IONIC_FEC_STAT(dst, src) \
+ do { \
+ __le64 __val = READ_ONCE(src); \
+ \
+ if (__val != IONIC_STAT_INVALID) \
+ (dst) = le64_to_cpu(__val); \
+ } while (0)
+
+static const struct ethtool_fec_hist_range ionic_fec_hist_ranges[] = {
+ { 0, 0},
+ { 1, 1},
+ { 2, 2},
+ { 3, 3},
+ { 4, 4},
+ { 5, 5},
+ { 6, 6},
+ { 7, 7},
+ { 8, 8},
+ { 9, 9},
+ { 10, 10},
+ { 11, 11},
+ { 12, 12},
+ { 13, 13},
+ { 14, 14},
+ { 15, 15},
+ { 0, 0},
+};
+
+static void
+ionic_fill_fec_hist(const struct ionic_port_extra_stats *port_extra_stats,
+ struct ethtool_fec_hist *hist)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(port_extra_stats->fec_codeword_error_bin); i++) {
+ __le64 val = READ_ONCE(port_extra_stats->fec_codeword_error_bin[i]);
+
+ if (val == IONIC_STAT_INVALID)
+ return;
+
+ hist->values[i].sum = le64_to_cpu(val);
+ }
+
+ hist->ranges = ionic_fec_hist_ranges;
+}
+
+static void ionic_get_fec_stats(struct net_device *netdev,
+ struct ethtool_fec_stats *fec_stats,
+ struct ethtool_fec_hist *hist)
+{
+ struct ionic_lif *lif = netdev_priv(netdev);
+ struct ionic_port_info *port_info;
+
+ if (lif->ionic->pdev->is_virtfn)
+ return;
+
+ if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
+ return;
+
+ if (!(lif->ionic->ident.dev.capabilities &
+ cpu_to_le64(IONIC_DEV_CAP_EXTRA_STATS)))
+ return;
+
+ port_info = lif->ionic->idev.port_info;
+ if (!port_info) {
+ netdev_err_once(netdev, "port_info not initialized\n");
+ return;
+ }
+
+ if (READ_ONCE(port_info->status.fec_type) != IONIC_PORT_FEC_TYPE_RS)
+ return;
+
+ IONIC_FEC_STAT(fec_stats->corrected_blocks.total,
+ port_info->extra_stats.rsfec_correctable_blocks);
+ IONIC_FEC_STAT(fec_stats->uncorrectable_blocks.total,
+ port_info->extra_stats.rsfec_uncorrectable_blocks);
+ IONIC_FEC_STAT(fec_stats->corrected_bits.total,
+ port_info->extra_stats.fec_corrected_bits_total);
+
+ ionic_fill_fec_hist(&port_info->extra_stats, hist);
+}
+
static int ionic_set_fecparam(struct net_device *netdev,
struct ethtool_fecparam *fec)
{
@@ -1184,6 +1266,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
.get_module_eeprom_by_page = ionic_get_module_eeprom_by_page,
.get_pauseparam = ionic_get_pauseparam,
.set_pauseparam = ionic_set_pauseparam,
+ .get_fec_stats = ionic_get_fec_stats,
.get_fecparam = ionic_get_fecparam,
.set_fecparam = ionic_set_fecparam,
.get_ts_info = ionic_get_ts_info,
--
2.53.0
next prev parent reply other threads:[~2026-11-04 21:20 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 21:19 [PATCH net-next v3 0/5] ionic: FEC reporting fixes and .get_fec_stats handler Eric Joyner
2026-11-04 21:19 ` [PATCH net-next v3 1/5] ionic: write the extra_stats invalid markers one counter at a time Eric Joyner
2026-11-04 21:19 ` [PATCH net-next v3 2/5] ionic: report the configured FEC mode in ethtool_fecparam.fec Eric Joyner
2026-11-10 21:26 ` Jakub Kicinski
2026-11-04 21:19 ` [PATCH net-next v3 3/5] ionic: map the FEC type through a helper in ionic_get_fecparam() Eric Joyner
2026-11-04 21:19 ` [PATCH net-next v3 4/5] ionic: report the operational FEC mode from ethtool --show-fec Eric Joyner
2026-11-10 21:26 ` Jakub Kicinski
2026-11-04 21:19 ` Eric Joyner [this message]
2026-11-09 19:35 ` [PATCH net-next v3 0/5] ionic: FEC reporting fixes and .get_fec_stats handler Eric Joyner
-- strict thread matches above, loose matches on Subject: below --
2026-05-12 22:44 [PATCH net-next v3 0/5] Expose more port stats to ethtool Eric Joyner
2026-05-12 22:44 ` [PATCH net-next v3 5/5] ionic: Add .get_fec_stats ethtool handler Eric Joyner
2026-05-15 1:32 ` Jakub Kicinski
2026-05-15 19:59 ` Eric Joyner
2026-05-15 23:02 ` Jakub Kicinski
2026-05-19 0:06 ` Eric Joyner
2026-05-19 0:22 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104-ionic-get-fec-stats-v3-5-b261fd53d0a7@amd.com \
--to=eric.joyner@amd.com \
--cc=andrew+netdev@lunn.ch \
--cc=brett.creeley@amd.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nikhil.rao@amd.com \
--cc=pabeni@redhat.com \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox