* [PATCH net-next v2 1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:31 ` Jacob Keller
2025-08-25 20:02 ` [PATCH net-next v2 2/6] eth: fbnic: Reset hw stats upon PCI error Jakub Kicinski
` (5 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Move hw_stats_lock out of fbnic_dev to a more appropriate struct
fbnic_hw_stats since the only use of this lock is to protect access to
the hardware stats. While at it, enclose the lock and stats
initialization in a single init call.
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic.h | 3 ---
.../net/ethernet/meta/fbnic/fbnic_hw_stats.h | 5 ++++
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 4 ++--
.../net/ethernet/meta/fbnic/fbnic_hw_stats.c | 23 ++++++++++++-------
.../net/ethernet/meta/fbnic/fbnic_netdev.c | 12 +++++-----
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 3 +--
6 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index c376e06880c9..311c7dda911a 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -84,9 +84,6 @@ struct fbnic_dev {
/* Local copy of hardware statistics */
struct fbnic_hw_stats hw_stats;
- /* Lock protecting access to hw_stats */
- spinlock_t hw_stats_lock;
-
struct fbnic_fw_log fw_log;
};
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
index 4fe239717497..2fc25074a5e6 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
@@ -5,6 +5,7 @@
#define _FBNIC_HW_STATS_H_
#include <linux/ethtool.h>
+#include <linux/spinlock.h>
#include "fbnic_csr.h"
@@ -122,11 +123,15 @@ struct fbnic_hw_stats {
struct fbnic_rxb_stats rxb;
struct fbnic_hw_q_stats hw_q[FBNIC_MAX_QUEUES];
struct fbnic_pcie_stats pcie;
+
+ /* Lock protecting the access to hw stats */
+ spinlock_t lock;
};
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset);
void fbnic_reset_hw_stats(struct fbnic_dev *fbd);
+void fbnic_init_hw_stats(struct fbnic_dev *fbd);
void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
struct fbnic_hw_q_stats *hw_q);
void fbnic_get_hw_stats32(struct fbnic_dev *fbd);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index a758f510f886..e6a60d7ea864 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -518,7 +518,7 @@ static void fbnic_get_ethtool_stats(struct net_device *dev,
fbnic_get_hw_stats(fbn->fbd);
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
fbnic_report_hw_stats(fbnic_gstrings_hw_stats, &fbd->hw_stats,
FBNIC_HW_FIXED_STATS_LEN, &data);
@@ -555,7 +555,7 @@ static void fbnic_get_ethtool_stats(struct net_device *dev,
fbnic_report_hw_stats(fbnic_gstrings_hw_q_stats, hw_q,
FBNIC_HW_Q_STATS_LEN, &data);
}
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
for (i = 0; i < FBNIC_MAX_XDPQS; i++)
fbnic_get_xdp_queue_stats(fbn->tx[i + FBNIC_MAX_TXQS], &data);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
index 4223d8100e64..77182922f018 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
@@ -421,9 +421,9 @@ static void fbnic_get_hw_rxq_stats32(struct fbnic_dev *fbd,
void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
struct fbnic_hw_q_stats *hw_q)
{
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
fbnic_get_hw_rxq_stats32(fbd, hw_q);
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
}
static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd,
@@ -512,14 +512,21 @@ static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
{
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi);
fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti);
fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
fbnic_reset_rxb_stats(fbd, &fbd->hw_stats.rxb);
fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q);
fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
+}
+
+void fbnic_init_hw_stats(struct fbnic_dev *fbd)
+{
+ spin_lock_init(&fbd->hw_stats.lock);
+
+ fbnic_reset_hw_stats(fbd);
}
static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
@@ -533,19 +540,19 @@ static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
void fbnic_get_hw_stats32(struct fbnic_dev *fbd)
{
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
__fbnic_get_hw_stats32(fbd);
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
}
void fbnic_get_hw_stats(struct fbnic_dev *fbd)
{
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
__fbnic_get_hw_stats32(fbd);
fbnic_get_tmi_stats(fbd, &fbd->hw_stats.tmi);
fbnic_get_tti_stats(fbd, &fbd->hw_stats.tti);
fbnic_get_rxb_stats(fbd, &fbd->hw_stats.rxb);
fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie);
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index b8b684ad376b..98602bc3b39f 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -424,12 +424,12 @@ static void fbnic_get_stats64(struct net_device *dev,
tx_dropped = stats->dropped;
/* Record drops from Tx HW Datapath */
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
tx_dropped += fbd->hw_stats.tmi.drop.frames.value +
fbd->hw_stats.tti.cm_drop.frames.value +
fbd->hw_stats.tti.frame_drop.frames.value +
fbd->hw_stats.tti.tbi_drop.frames.value;
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
stats64->tx_bytes = tx_bytes;
stats64->tx_packets = tx_packets;
@@ -460,7 +460,7 @@ static void fbnic_get_stats64(struct net_device *dev,
rx_packets = stats->packets;
rx_dropped = stats->dropped;
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
/* Record drops for the host FIFOs.
* 4: network to Host, 6: BMC to Host
* Exclude the BMC and MC FIFOs as those stats may contain drops
@@ -480,7 +480,7 @@ static void fbnic_get_stats64(struct net_device *dev,
/* Report packets with errors */
rx_errors += fbd->hw_stats.hw_q[i].rde_pkt_err.value;
}
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
stats64->rx_bytes = rx_bytes;
stats64->rx_packets = rx_packets;
@@ -608,12 +608,12 @@ static void fbnic_get_queue_stats_rx(struct net_device *dev, int idx,
fbnic_get_hw_q_stats(fbd, fbd->hw_stats.hw_q);
- spin_lock(&fbd->hw_stats_lock);
+ spin_lock(&fbd->hw_stats.lock);
rx->hw_drop_overruns = fbd->hw_stats.hw_q[idx].rde_pkt_cq_drop.value +
fbd->hw_stats.hw_q[idx].rde_pkt_bdq_drop.value;
rx->hw_drops = fbd->hw_stats.hw_q[idx].rde_pkt_err.value +
rx->hw_drop_overruns;
- spin_unlock(&fbd->hw_stats_lock);
+ spin_unlock(&fbd->hw_stats.lock);
}
static void fbnic_get_queue_stats_tx(struct net_device *dev, int idx,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index b70e4cadb37b..8190f49e1426 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -304,10 +304,9 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
fbnic_devlink_register(fbd);
fbnic_dbg_fbd_init(fbd);
- spin_lock_init(&fbd->hw_stats_lock);
/* Capture snapshot of hardware stats so netdev can calculate delta */
- fbnic_reset_hw_stats(fbd);
+ fbnic_init_hw_stats(fbd);
fbnic_hwmon_register(fbd);
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev
2025-08-25 20:02 ` [PATCH net-next v2 1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev Jakub Kicinski
@ 2025-08-26 23:31 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:31 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 520 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Move hw_stats_lock out of fbnic_dev to a more appropriate struct
> fbnic_hw_stats since the only use of this lock is to protect access to
> the hardware stats. While at it, enclose the lock and stats
> initialization in a single init call.
>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v2 2/6] eth: fbnic: Reset hw stats upon PCI error
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
2025-08-25 20:02 ` [PATCH net-next v2 1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:32 ` Jacob Keller
2025-08-25 20:02 ` [PATCH net-next v2 3/6] eth: fbnic: Reset MAC stats Jakub Kicinski
` (4 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Upon experiencing a PCI error, fbnic reset the device to recover from
the failure. Reset the hardware stats as part of the device reset to
ensure accurate stats reporting.
Note that the reset is not really resetting the aggregate value to 0,
which may result in a spike for a system collecting deltas in stats.
Rather, the reset re-latches the current value as previous, in case HW
got reset.
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 8190f49e1426..953297f667a2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -491,6 +491,8 @@ static void __fbnic_pm_attach(struct device *dev)
struct net_device *netdev = fbd->netdev;
struct fbnic_net *fbn;
+ fbnic_reset_hw_stats(fbd);
+
if (fbnic_init_failure(fbd))
return;
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 2/6] eth: fbnic: Reset hw stats upon PCI error
2025-08-25 20:02 ` [PATCH net-next v2 2/6] eth: fbnic: Reset hw stats upon PCI error Jakub Kicinski
@ 2025-08-26 23:32 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:32 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 1429 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Upon experiencing a PCI error, fbnic reset the device to recover from
> the failure. Reset the hardware stats as part of the device reset to
> ensure accurate stats reporting.
>
> Note that the reset is not really resetting the aggregate value to 0,
> which may result in a spike for a system collecting deltas in stats.
> Rather, the reset re-latches the current value as previous, in case HW
> got reset.
>
Good. This means stats should stay relatively stable across reset, while
preventing glitches if the HW stat itself reset. Makes sense.
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
> index 8190f49e1426..953297f667a2 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
> @@ -491,6 +491,8 @@ static void __fbnic_pm_attach(struct device *dev)
> struct net_device *netdev = fbd->netdev;
> struct fbnic_net *fbn;
>
> + fbnic_reset_hw_stats(fbd);
> +
> if (fbnic_init_failure(fbd))
> return;
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v2 3/6] eth: fbnic: Reset MAC stats
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
2025-08-25 20:02 ` [PATCH net-next v2 1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev Jakub Kicinski
2025-08-25 20:02 ` [PATCH net-next v2 2/6] eth: fbnic: Reset hw stats upon PCI error Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:33 ` Jacob Keller
2025-08-25 20:02 ` [PATCH net-next v2 4/6] eth: fbnic: Fetch PHY stats from device Jakub Kicinski
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Reset the MAC stats as part of the hardware stats reset to ensure
consistency. Currently, hardware stats are reset during device bring-up
and upon experiencing PCI errors; however, MAC stats are being skipped
during these resets.
When fbnic_reset_hw_stats() is called upon recovering from PCI error,
MAC stats are accessed outside the rtnl_lock. The only other access to
MAC stats is via the ethtool API, which is protected by rtnl_lock. This
can result in concurrent access to MAC stats and a potential race. Protect
the fbnic_reset_hw_stats() call in __fbnic_pm_attach() with rtnl_lock to
avoid this.
Note that fbnic_reset_hw_mac_stats() is called outside the hardware
stats lock which protects access to the fbnic_hw_stats. This is intentional
because MAC stats are fetched from the device outside this lock and are
exclusively read via the ethtool API.
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_hw_stats.c | 22 +++++++++++++++++++
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 ++
2 files changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
index 77182922f018..8aa9a0e286bb 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
+#include <linux/rtnetlink.h>
+
#include "fbnic.h"
static void fbnic_hw_stat_rst32(struct fbnic_dev *fbd, u32 reg,
@@ -510,6 +512,16 @@ static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
&pcie->ob_rd_no_np_cred);
}
+static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd,
+ struct fbnic_mac_stats *mac_stats)
+{
+ const struct fbnic_mac *mac = fbd->mac;
+
+ mac->get_eth_mac_stats(fbd, true, &mac_stats->eth_mac);
+ mac->get_eth_ctrl_stats(fbd, true, &mac_stats->eth_ctrl);
+ mac->get_rmon_stats(fbd, true, &mac_stats->rmon);
+}
+
void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
{
spin_lock(&fbd->hw_stats.lock);
@@ -520,6 +532,16 @@ void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q);
fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
spin_unlock(&fbd->hw_stats.lock);
+
+ /* Once registered, the only other access to MAC stats is via the
+ * ethtool API which is protected by the rtnl_lock. The call to
+ * fbnic_reset_hw_stats() during PCI recovery is also protected
+ * by the rtnl_lock hence, we don't need the spinlock to access
+ * the MAC stats.
+ */
+ if (fbd->netdev)
+ ASSERT_RTNL();
+ fbnic_reset_hw_mac_stats(fbd, &fbd->hw_stats.mac);
}
void fbnic_init_hw_stats(struct fbnic_dev *fbd)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 953297f667a2..ef7928b18ac0 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -491,7 +491,9 @@ static void __fbnic_pm_attach(struct device *dev)
struct net_device *netdev = fbd->netdev;
struct fbnic_net *fbn;
+ rtnl_lock();
fbnic_reset_hw_stats(fbd);
+ rtnl_unlock();
if (fbnic_init_failure(fbd))
return;
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 3/6] eth: fbnic: Reset MAC stats
2025-08-25 20:02 ` [PATCH net-next v2 3/6] eth: fbnic: Reset MAC stats Jakub Kicinski
@ 2025-08-26 23:33 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:33 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 1183 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Reset the MAC stats as part of the hardware stats reset to ensure
> consistency. Currently, hardware stats are reset during device bring-up
> and upon experiencing PCI errors; however, MAC stats are being skipped
> during these resets.
>
> When fbnic_reset_hw_stats() is called upon recovering from PCI error,
> MAC stats are accessed outside the rtnl_lock. The only other access to
> MAC stats is via the ethtool API, which is protected by rtnl_lock. This
> can result in concurrent access to MAC stats and a potential race. Protect
> the fbnic_reset_hw_stats() call in __fbnic_pm_attach() with rtnl_lock to
> avoid this.
>
> Note that fbnic_reset_hw_mac_stats() is called outside the hardware
> stats lock which protects access to the fbnic_hw_stats. This is intentional
> because MAC stats are fetched from the device outside this lock and are
> exclusively read via the ethtool API.
>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v2 4/6] eth: fbnic: Fetch PHY stats from device
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
` (2 preceding siblings ...)
2025-08-25 20:02 ` [PATCH net-next v2 3/6] eth: fbnic: Reset MAC stats Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:35 ` Jacob Keller
2025-08-25 20:02 ` [PATCH net-next v2 5/6] eth: fbnic: Read PHY stats via the ethtool API Jakub Kicinski
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Add support to fetch PHY stats consisting of PCS and FEC stats from the
device. When reading the stats counters, the lo part is read first, which
latches the hi part to ensure consistent reading of the stats counter.
FEC and PCS stats can wrap depending on the access frequency. To prevent
wrapping, fetch these stats periodically under the service task. Also to
maintain consistency fetch these stats along with other 32b stats under
__fbnic_get_hw_stats32().
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 15 ++++++
.../net/ethernet/meta/fbnic/fbnic_hw_stats.h | 16 +++++++
drivers/net/ethernet/meta/fbnic/fbnic_mac.h | 4 ++
.../net/ethernet/meta/fbnic/fbnic_hw_stats.c | 20 ++++++++
drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 46 +++++++++++++++++++
5 files changed, 101 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index a81db842aa53..69cb73ca8bca 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -790,6 +790,21 @@ enum {
#define FBNIC_CSR_END_PCS 0x10668 /* CSR section delimiter */
#define FBNIC_CSR_START_RSFEC 0x10800 /* CSR section delimiter */
+
+/* We have 4 RSFEC engines present in our part, however we are only using 1.
+ * As such only CCW(0) and NCCW(0) will never be non-zero and the other
+ * registers can be ignored.
+ */
+#define FBNIC_RSFEC_CCW_LO(n) (0x10802 + 8 * (n)) /* 0x42008 + 32*n */
+#define FBNIC_RSFEC_CCW_HI(n) (0x10803 + 8 * (n)) /* 0x4200c + 32*n */
+#define FBNIC_RSFEC_NCCW_LO(n) (0x10804 + 8 * (n)) /* 0x42010 + 32*n */
+#define FBNIC_RSFEC_NCCW_HI(n) (0x10805 + 8 * (n)) /* 0x42014 + 32*n */
+
+#define FBNIC_PCS_MAX_LANES 4
+#define FBNIC_PCS_SYMBLERR_LO(n) \
+ (0x10880 + 2 * (n)) /* 0x42200 + 8*n */
+#define FBNIC_PCS_SYMBLERR_HI(n) \
+ (0x10881 + 2 * (n)) /* 0x42204 + 8*n */
#define FBNIC_CSR_END_RSFEC 0x108c8 /* CSR section delimiter */
/* MAC MAC registers (ASIC only) */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
index 2fc25074a5e6..baffae1868a6 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
@@ -23,6 +23,16 @@ struct fbnic_hw_stat {
struct fbnic_stat_counter bytes;
};
+struct fbnic_fec_stats {
+ struct fbnic_stat_counter corrected_blocks, uncorrectable_blocks;
+};
+
+struct fbnic_pcs_stats {
+ struct {
+ struct fbnic_stat_counter lanes[FBNIC_PCS_MAX_LANES];
+ } SymbolErrorDuringCarrier;
+};
+
/* Note: not updated by fbnic_get_hw_stats() */
struct fbnic_eth_ctrl_stats {
struct fbnic_stat_counter MACControlFramesTransmitted;
@@ -56,6 +66,11 @@ struct fbnic_eth_mac_stats {
struct fbnic_stat_counter FrameTooLongErrors;
};
+struct fbnic_phy_stats {
+ struct fbnic_fec_stats fec;
+ struct fbnic_pcs_stats pcs;
+};
+
struct fbnic_mac_stats {
struct fbnic_eth_mac_stats eth_mac;
struct fbnic_eth_ctrl_stats eth_ctrl;
@@ -116,6 +131,7 @@ struct fbnic_pcie_stats {
};
struct fbnic_hw_stats {
+ struct fbnic_phy_stats phy;
struct fbnic_mac_stats mac;
struct fbnic_tmi_stats tmi;
struct fbnic_tti_stats tti;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
index 86fa06da2b3e..92dd6efb920a 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
@@ -79,6 +79,10 @@ struct fbnic_mac {
bool (*pcs_get_link)(struct fbnic_dev *fbd);
int (*pcs_get_link_event)(struct fbnic_dev *fbd);
+ void (*get_fec_stats)(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_fec_stats *fec_stats);
+ void (*get_pcs_stats)(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_pcs_stats *pcs_stats);
void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset,
struct fbnic_eth_mac_stats *mac_stats);
void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
index 8aa9a0e286bb..9e7becba7386 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
@@ -512,6 +512,24 @@ static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
&pcie->ob_rd_no_np_cred);
}
+static void fbnic_reset_phy_stats(struct fbnic_dev *fbd,
+ struct fbnic_phy_stats *phy_stats)
+{
+ const struct fbnic_mac *mac = fbd->mac;
+
+ mac->get_fec_stats(fbd, true, &phy_stats->fec);
+ mac->get_pcs_stats(fbd, true, &phy_stats->pcs);
+}
+
+static void fbnic_get_phy_stats32(struct fbnic_dev *fbd,
+ struct fbnic_phy_stats *phy_stats)
+{
+ const struct fbnic_mac *mac = fbd->mac;
+
+ mac->get_fec_stats(fbd, false, &phy_stats->fec);
+ mac->get_pcs_stats(fbd, false, &phy_stats->pcs);
+}
+
static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd,
struct fbnic_mac_stats *mac_stats)
{
@@ -525,6 +543,7 @@ static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd,
void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
{
spin_lock(&fbd->hw_stats.lock);
+ fbnic_reset_phy_stats(fbd, &fbd->hw_stats.phy);
fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi);
fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti);
fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
@@ -553,6 +572,7 @@ void fbnic_init_hw_stats(struct fbnic_dev *fbd)
static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
{
+ fbnic_get_phy_stats32(fbd, &fbd->hw_stats.phy);
fbnic_get_tmi_stats32(fbd, &fbd->hw_stats.tmi);
fbnic_get_tti_stats32(fbd, &fbd->hw_stats.tti);
fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
index fd8d67f9048e..ffdaebd4002a 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
@@ -631,6 +631,50 @@ static void fbnic_mac_link_up_asic(struct fbnic_dev *fbd,
wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg);
}
+static void
+fbnic_pcs_rsfec_stat_rd32(struct fbnic_dev *fbd, u32 reg, bool reset,
+ struct fbnic_stat_counter *stat)
+{
+ u32 pcs_rsfec_stat;
+
+ /* The PCS/RFSEC registers are only 16b wide each. So what we will
+ * have after the 64b read is 0x0000xxxx0000xxxx. To make it usable
+ * as a full stat we will shift the upper bits into the lower set of
+ * 0s and then mask off the math at 32b.
+ *
+ * Read ordering must be lower reg followed by upper reg.
+ */
+ pcs_rsfec_stat = rd32(fbd, reg) & 0xffff;
+ pcs_rsfec_stat |= rd32(fbd, reg + 1) << 16;
+
+ /* RFSEC registers clear themselves upon being read so there is no
+ * need to store the old_reg_value.
+ */
+ if (!reset)
+ stat->value += pcs_rsfec_stat;
+}
+
+static void
+fbnic_mac_get_fec_stats(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_fec_stats *s)
+{
+ fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_CCW_LO(0), reset,
+ &s->corrected_blocks);
+ fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_NCCW_LO(0), reset,
+ &s->uncorrectable_blocks);
+}
+
+static void
+fbnic_mac_get_pcs_stats(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_pcs_stats *s)
+{
+ int i;
+
+ for (i = 0; i < FBNIC_PCS_MAX_LANES; i++)
+ fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_PCS_SYMBLERR_LO(i), reset,
+ &s->SymbolErrorDuringCarrier.lanes[i]);
+}
+
static void
fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
struct fbnic_eth_mac_stats *mac_stats)
@@ -809,6 +853,8 @@ static const struct fbnic_mac fbnic_mac_asic = {
.pcs_disable = fbnic_pcs_disable_asic,
.pcs_get_link = fbnic_pcs_get_link_asic,
.pcs_get_link_event = fbnic_pcs_get_link_event_asic,
+ .get_fec_stats = fbnic_mac_get_fec_stats,
+ .get_pcs_stats = fbnic_mac_get_pcs_stats,
.get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
.get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats,
.get_rmon_stats = fbnic_mac_get_rmon_stats,
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 4/6] eth: fbnic: Fetch PHY stats from device
2025-08-25 20:02 ` [PATCH net-next v2 4/6] eth: fbnic: Fetch PHY stats from device Jakub Kicinski
@ 2025-08-26 23:35 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:35 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 762 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Add support to fetch PHY stats consisting of PCS and FEC stats from the
> device. When reading the stats counters, the lo part is read first, which
> latches the hi part to ensure consistent reading of the stats counter.
>
> FEC and PCS stats can wrap depending on the access frequency. To prevent
> wrapping, fetch these stats periodically under the service task. Also to
> maintain consistency fetch these stats along with other 32b stats under
> __fbnic_get_hw_stats32().
>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v2 5/6] eth: fbnic: Read PHY stats via the ethtool API
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
` (3 preceding siblings ...)
2025-08-25 20:02 ` [PATCH net-next v2 4/6] eth: fbnic: Fetch PHY stats from device Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:35 ` Jacob Keller
2025-08-25 20:02 ` [PATCH net-next v2 6/6] eth: fbnic: Add pause stats support Jakub Kicinski
2025-08-28 2:00 ` [PATCH net-next v2 0/6] eth: fbnic: Extend hw " patchwork-bot+netdevbpf
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Provide support to read PHY stats (FEC and PCS) via the ethtool API.
]# ethtool -I --show-fec eth0
FEC parameters for eth0:
Supported/Configured FEC encodings: RS
Active FEC encoding: RS
Statistics:
corrected_blocks: 0
uncorrectable_blocks: 0
]# ethtool -S eth0 --groups eth-phy
Standard stats for eth0:
eth-phy-SymbolErrorDuringCarrier: 0
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index e6a60d7ea864..4194b30f1074 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -1641,6 +1641,46 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
*stat = counter->value;
}
+static void
+fbnic_get_fec_stats(struct net_device *netdev,
+ struct ethtool_fec_stats *fec_stats)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_phy_stats *phy_stats;
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ fbnic_get_hw_stats32(fbd);
+ phy_stats = &fbd->hw_stats.phy;
+
+ spin_lock(&fbd->hw_stats.lock);
+ fec_stats->corrected_blocks.total =
+ phy_stats->fec.corrected_blocks.value;
+ fec_stats->uncorrectable_blocks.total =
+ phy_stats->fec.uncorrectable_blocks.value;
+ spin_unlock(&fbd->hw_stats.lock);
+}
+
+static void
+fbnic_get_eth_phy_stats(struct net_device *netdev,
+ struct ethtool_eth_phy_stats *eth_phy_stats)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_phy_stats *phy_stats;
+ struct fbnic_dev *fbd = fbn->fbd;
+ u64 total = 0;
+ int i;
+
+ fbnic_get_hw_stats32(fbd);
+ phy_stats = &fbd->hw_stats.phy;
+
+ spin_lock(&fbd->hw_stats.lock);
+ for (i = 0; i < FBNIC_PCS_MAX_LANES; i++)
+ total += phy_stats->pcs.SymbolErrorDuringCarrier.lanes[i].value;
+
+ eth_phy_stats->SymbolErrorDuringCarrier = total;
+ spin_unlock(&fbd->hw_stats.lock);
+}
+
static void
fbnic_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *eth_mac_stats)
@@ -1782,7 +1822,9 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.get_ts_info = fbnic_get_ts_info,
.get_ts_stats = fbnic_get_ts_stats,
.get_link_ksettings = fbnic_phylink_ethtool_ksettings_get,
+ .get_fec_stats = fbnic_get_fec_stats,
.get_fecparam = fbnic_phylink_get_fecparam,
+ .get_eth_phy_stats = fbnic_get_eth_phy_stats,
.get_eth_mac_stats = fbnic_get_eth_mac_stats,
.get_eth_ctrl_stats = fbnic_get_eth_ctrl_stats,
.get_rmon_stats = fbnic_get_rmon_stats,
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 5/6] eth: fbnic: Read PHY stats via the ethtool API
2025-08-25 20:02 ` [PATCH net-next v2 5/6] eth: fbnic: Read PHY stats via the ethtool API Jakub Kicinski
@ 2025-08-26 23:35 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:35 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 661 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Provide support to read PHY stats (FEC and PCS) via the ethtool API.
>
> ]# ethtool -I --show-fec eth0
> FEC parameters for eth0:
> Supported/Configured FEC encodings: RS
> Active FEC encoding: RS
> Statistics:
> corrected_blocks: 0
> uncorrectable_blocks: 0
>
> ]# ethtool -S eth0 --groups eth-phy
> Standard stats for eth0:
> eth-phy-SymbolErrorDuringCarrier: 0
>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v2 6/6] eth: fbnic: Add pause stats support
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
` (4 preceding siblings ...)
2025-08-25 20:02 ` [PATCH net-next v2 5/6] eth: fbnic: Read PHY stats via the ethtool API Jakub Kicinski
@ 2025-08-25 20:02 ` Jakub Kicinski
2025-08-26 23:36 ` Jacob Keller
2025-08-28 2:00 ` [PATCH net-next v2 0/6] eth: fbnic: Extend hw " patchwork-bot+netdevbpf
6 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2025-08-25 20:02 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko, jacob.e.keller, Jakub Kicinski
From: Mohsin Bashir <mohsin.bashr@gmail.com>
Add support to read pause stats for fbnic. Unlike FEC and PCS stats,
pause stats won't wrap, do not fetch them under the service task. Since,
they are exclusively accessed via the ethtool API, don't include them in
fbnic_get_hw_stats().
]# ethtool -I -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: off
TX: off
Statistics:
tx_pause_frames: 0
rx_pause_frames: 0
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 4 ++++
.../net/ethernet/meta/fbnic/fbnic_hw_stats.h | 7 +++++++
drivers/net/ethernet/meta/fbnic/fbnic_mac.h | 2 ++
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 17 +++++++++++++++++
.../net/ethernet/meta/fbnic/fbnic_hw_stats.c | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 11 +++++++++++
6 files changed, 42 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index 69cb73ca8bca..e2fffe1597e9 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -844,6 +844,10 @@ enum {
#define FBNIC_CSR_END_SIG 0x1184e /* CSR section delimiter */
#define FBNIC_CSR_START_MAC_STAT 0x11a00
+#define FBNIC_MAC_STAT_RX_XOFF_STB_L 0x11a00 /* 0x46800 */
+#define FBNIC_MAC_STAT_RX_XOFF_STB_H 0x11a01 /* 0x46804 */
+#define FBNIC_MAC_STAT_TX_XOFF_STB_L 0x11a04 /* 0x46810 */
+#define FBNIC_MAC_STAT_TX_XOFF_STB_H 0x11a05 /* 0x46814 */
#define FBNIC_MAC_STAT_RX_BYTE_COUNT_L 0x11a08 /* 0x46820 */
#define FBNIC_MAC_STAT_RX_BYTE_COUNT_H 0x11a09 /* 0x46824 */
#define FBNIC_MAC_STAT_RX_ALIGN_ERROR_L 0x11a0a /* 0x46828 */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
index baffae1868a6..aa3f429a9aed 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
@@ -50,6 +50,12 @@ struct fbnic_rmon_stats {
struct fbnic_stat_counter hist_tx[ETHTOOL_RMON_HIST_MAX];
};
+/* Note: not updated by fbnic_get_hw_stats() */
+struct fbnic_pause_stats {
+ struct fbnic_stat_counter tx_pause_frames;
+ struct fbnic_stat_counter rx_pause_frames;
+};
+
struct fbnic_eth_mac_stats {
struct fbnic_stat_counter FramesTransmittedOK;
struct fbnic_stat_counter FramesReceivedOK;
@@ -73,6 +79,7 @@ struct fbnic_phy_stats {
struct fbnic_mac_stats {
struct fbnic_eth_mac_stats eth_mac;
+ struct fbnic_pause_stats pause;
struct fbnic_eth_ctrl_stats eth_ctrl;
struct fbnic_rmon_stats rmon;
};
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
index 92dd6efb920a..ede5ff0dae22 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
@@ -85,6 +85,8 @@ struct fbnic_mac {
struct fbnic_pcs_stats *pcs_stats);
void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset,
struct fbnic_eth_mac_stats *mac_stats);
+ void (*get_pause_stats)(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_pause_stats *pause_stats);
void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset,
struct fbnic_eth_ctrl_stats *ctrl_stats);
void (*get_rmon_stats)(struct fbnic_dev *fbd, bool reset,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index 4194b30f1074..b4ff98ee2051 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -1641,6 +1641,22 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
*stat = counter->value;
}
+static void
+fbnic_get_pause_stats(struct net_device *netdev,
+ struct ethtool_pause_stats *pause_stats)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_mac_stats *mac_stats;
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ mac_stats = &fbd->hw_stats.mac;
+
+ fbd->mac->get_pause_stats(fbd, false, &mac_stats->pause);
+
+ pause_stats->tx_pause_frames = mac_stats->pause.tx_pause_frames.value;
+ pause_stats->rx_pause_frames = mac_stats->pause.rx_pause_frames.value;
+}
+
static void
fbnic_get_fec_stats(struct net_device *netdev,
struct ethtool_fec_stats *fec_stats)
@@ -1801,6 +1817,7 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.set_coalesce = fbnic_set_coalesce,
.get_ringparam = fbnic_get_ringparam,
.set_ringparam = fbnic_set_ringparam,
+ .get_pause_stats = fbnic_get_pause_stats,
.get_pauseparam = fbnic_phylink_get_pauseparam,
.set_pauseparam = fbnic_phylink_set_pauseparam,
.get_strings = fbnic_get_strings,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
index 9e7becba7386..8b9b2076beec 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
@@ -536,6 +536,7 @@ static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd,
const struct fbnic_mac *mac = fbd->mac;
mac->get_eth_mac_stats(fbd, true, &mac_stats->eth_mac);
+ mac->get_pause_stats(fbd, true, &mac_stats->pause);
mac->get_eth_ctrl_stats(fbd, true, &mac_stats->eth_ctrl);
mac->get_rmon_stats(fbd, true, &mac_stats->rmon);
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
index ffdaebd4002a..8f998d26b9a3 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
@@ -709,6 +709,16 @@ fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
MAC_STAT_TX_BROADCAST);
}
+static void
+fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset,
+ struct fbnic_pause_stats *pause_stats)
+{
+ fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames,
+ MAC_STAT_TX_XOFF_STB);
+ fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames,
+ MAC_STAT_RX_XOFF_STB);
+}
+
static void
fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev *fbd, bool reset,
struct fbnic_eth_ctrl_stats *ctrl_stats)
@@ -856,6 +866,7 @@ static const struct fbnic_mac fbnic_mac_asic = {
.get_fec_stats = fbnic_mac_get_fec_stats,
.get_pcs_stats = fbnic_mac_get_pcs_stats,
.get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
+ .get_pause_stats = fbnic_mac_get_pause_stats,
.get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats,
.get_rmon_stats = fbnic_mac_get_rmon_stats,
.link_down = fbnic_mac_link_down_asic,
--
2.51.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 6/6] eth: fbnic: Add pause stats support
2025-08-25 20:02 ` [PATCH net-next v2 6/6] eth: fbnic: Add pause stats support Jakub Kicinski
@ 2025-08-26 23:36 ` Jacob Keller
0 siblings, 0 replies; 14+ messages in thread
From: Jacob Keller @ 2025-08-26 23:36 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, mohsin.bashr,
vadim.fedorenko
[-- Attachment #1.1: Type: text/plain, Size: 694 bytes --]
On 8/25/2025 1:02 PM, Jakub Kicinski wrote:
> From: Mohsin Bashir <mohsin.bashr@gmail.com>
>
> Add support to read pause stats for fbnic. Unlike FEC and PCS stats,
> pause stats won't wrap, do not fetch them under the service task. Since,
> they are exclusively accessed via the ethtool API, don't include them in
> fbnic_get_hw_stats().
>
> ]# ethtool -I -a eth0
> Pause parameters for eth0:
> Autonegotiate: on
> RX: off
> TX: off
> Statistics:
> tx_pause_frames: 0
> rx_pause_frames: 0
>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support
2025-08-25 20:02 [PATCH net-next v2 0/6] eth: fbnic: Extend hw stats support Jakub Kicinski
` (5 preceding siblings ...)
2025-08-25 20:02 ` [PATCH net-next v2 6/6] eth: fbnic: Add pause stats support Jakub Kicinski
@ 2025-08-28 2:00 ` patchwork-bot+netdevbpf
6 siblings, 0 replies; 14+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-08-28 2:00 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms,
mohsin.bashr, vadim.fedorenko, jacob.e.keller
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 25 Aug 2025 13:02:00 -0700 you wrote:
> Mohsin says:
>
> Extend hardware stats support for fbnic by adding the ability to reset
> hardware stats when the device experience a reset due to a PCI error and
> include MAC stats in the hardware stats reset. Additionally, expand
> hardware stats coverage to include FEC, PHY, and Pause stats.
>
> [...]
Here is the summary with links:
- [net-next,v2,1/6] eth: fbnic: Move hw_stats_lock out of fbnic_dev
https://git.kernel.org/netdev/net-next/c/2ee5c8c0c28e
- [net-next,v2,2/6] eth: fbnic: Reset hw stats upon PCI error
https://git.kernel.org/netdev/net-next/c/b1161b1863c5
- [net-next,v2,3/6] eth: fbnic: Reset MAC stats
https://git.kernel.org/netdev/net-next/c/bcf54e5d7cd0
- [net-next,v2,4/6] eth: fbnic: Fetch PHY stats from device
https://git.kernel.org/netdev/net-next/c/df4c5d9a290e
- [net-next,v2,5/6] eth: fbnic: Read PHY stats via the ethtool API
https://git.kernel.org/netdev/net-next/c/33c493791bc0
- [net-next,v2,6/6] eth: fbnic: Add pause stats support
https://git.kernel.org/netdev/net-next/c/e9faf4db5f26
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 14+ messages in thread