2024-01-12 11:41:10

by Goud, Srinivas

[permalink] [raw]
Subject: [PATCH RESEND v7 0/3] can: xilinx_can: Add ECC feature support

Add ECC feature support to Tx and Rx FIFOs for Xilinx CAN Controller.
ECC is an IP configuration option where counter registers are added in
IP for 1bit/2bit ECC errors count and reset.
Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
interrupts.

Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
to support ECC if the ECC block is enabled in the HW.

Add ethtool stats interface for getting all the ECC errors information.

There is no public documentation for it available.

---
BRANCH: linux-can-next/master

Changes in v7:
Update with spinlock only for stats counters

Changes in v6:
Update commit description

Changes in v5:
Fix review comments
Change the sequence of updates the stats
Add get_strings and get_sset_count stats interface
Use u64 stats helper function

Changes in v4:
Fix DT binding check warning
Update xlnx,has-ecc property description

Changes in v3:
Update mailing list
Update commit description

Changes in v2:
Address review comments
Add ethtool stats interface
Update commit description

Srinivas Goud (3):
dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc' optional property
can: xilinx_can: Add ECC support
can: xilinx_can: Add ethtool stats interface for ECC errors

.../devicetree/bindings/net/can/xilinx,can.yaml | 5 +
drivers/net/can/xilinx_can.c | 159 ++++++++++++++++++++-
2 files changed, 160 insertions(+), 4 deletions(-)

--
2.1.1



2024-01-12 11:41:35

by Goud, Srinivas

[permalink] [raw]
Subject: [PATCH RESEND v7 1/3] dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc' optional property

ECC feature added to CAN TX_OL, TX_TL and RX FIFOs of
Xilinx AXI CAN Controller.
ECC is an IP configuration option where counter registers are added in
IP for 1bit/2bit ECC errors.

'xlnx,has-ecc' is an optional property and added to Xilinx AXI CAN Controller
node if ECC block enabled in the HW

Signed-off-by: Srinivas Goud <[email protected]>
Acked-by: Conor Dooley <[email protected]>
---
Changes in v7:
None

Changes in v6:
Update commit description
Add Acked-by tag

Changes in v5:
Update property description

Changes in v4:
Fix binding check warning
Update property description

Changes in v3:
Update commit description

Changes in v2:
None

Documentation/devicetree/bindings/net/can/xilinx,can.yaml | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/xilinx,can.yaml b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
index 64d57c3..8d4e5af 100644
--- a/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
+++ b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
@@ -49,6 +49,10 @@ properties:
resets:
maxItems: 1

+ xlnx,has-ecc:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: CAN TX_OL, TX_TL and RX FIFOs have ECC support(AXI CAN)
+
required:
- compatible
- reg
@@ -137,6 +141,7 @@ examples:
interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
tx-fifo-depth = <0x40>;
rx-fifo-depth = <0x40>;
+ xlnx,has-ecc;
};

- |
--
2.1.1


2024-01-12 11:42:01

by Goud, Srinivas

[permalink] [raw]
Subject: [PATCH RESEND v7 2/3] can: xilinx_can: Add ECC support

Add ECC support for Xilinx CAN Controller, so this driver reports
1bit/2bit ECC errors for FIFO's based on ECC error interrupt.
ECC feature for Xilinx CAN Controller selected through 'xlnx,has-ecc'
DT property

Signed-off-by: Srinivas Goud <[email protected]>
---
Changes in v7:
None

Changes in v6:
None

Changes in v5:
Address review comments
Change the sequence of updates the stats
Use u64 stats helper function

Changes in v4:
None

Changes in v3:
None

Changes in v2:
Address review comments

drivers/net/can/xilinx_can.c | 105 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 101 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index abe58f1..c8691a1 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -31,6 +31,7 @@
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include <linux/u64_stats_sync.h>

#define DRIVER_NAME "xilinx_can"

@@ -58,6 +59,13 @@ enum xcan_reg {
*/
XCAN_F_BTR_OFFSET = 0x08C, /* Data Phase Bit Timing */
XCAN_TRR_OFFSET = 0x0090, /* TX Buffer Ready Request */
+
+ /* only on AXI CAN cores */
+ XCAN_ECC_CFG_OFFSET = 0xC8, /* ECC Configuration */
+ XCAN_TXTLFIFO_ECC_OFFSET = 0xCC, /* TXTL FIFO ECC error counter */
+ XCAN_TXOLFIFO_ECC_OFFSET = 0xD0, /* TXOL FIFO ECC error counter */
+ XCAN_RXFIFO_ECC_OFFSET = 0xD4, /* RX FIFO ECC error counter */
+
XCAN_AFR_EXT_OFFSET = 0x00E0, /* Acceptance Filter */
XCAN_FSR_OFFSET = 0x00E8, /* RX FIFO Status */
XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */
@@ -124,6 +132,18 @@ enum xcan_reg {
#define XCAN_IXR_TXFLL_MASK 0x00000004 /* Tx FIFO Full intr */
#define XCAN_IXR_TXOK_MASK 0x00000002 /* TX successful intr */
#define XCAN_IXR_ARBLST_MASK 0x00000001 /* Arbitration lost intr */
+#define XCAN_IXR_E2BERX_MASK BIT(23) /* RX FIFO two bit ECC error */
+#define XCAN_IXR_E1BERX_MASK BIT(22) /* RX FIFO one bit ECC error */
+#define XCAN_IXR_E2BETXOL_MASK BIT(21) /* TXOL FIFO two bit ECC error */
+#define XCAN_IXR_E1BETXOL_MASK BIT(20) /* TXOL FIFO One bit ECC error */
+#define XCAN_IXR_E2BETXTL_MASK BIT(19) /* TXTL FIFO Two bit ECC error */
+#define XCAN_IXR_E1BETXTL_MASK BIT(18) /* TXTL FIFO One bit ECC error */
+#define XCAN_IXR_ECC_MASK (XCAN_IXR_E2BERX_MASK | \
+ XCAN_IXR_E1BERX_MASK | \
+ XCAN_IXR_E2BETXOL_MASK | \
+ XCAN_IXR_E1BETXOL_MASK | \
+ XCAN_IXR_E2BETXTL_MASK | \
+ XCAN_IXR_E1BETXTL_MASK)
#define XCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */
#define XCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */
#define XCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */
@@ -137,6 +157,11 @@ enum xcan_reg {
#define XCAN_2_FSR_RI_MASK 0x0000003F /* RX Read Index */
#define XCAN_DLCR_EDL_MASK 0x08000000 /* EDL Mask in DLC */
#define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */
+#define XCAN_ECC_CFG_REECRX_MASK BIT(2) /* Reset RX FIFO ECC error counters */
+#define XCAN_ECC_CFG_REECTXOL_MASK BIT(1) /* Reset TXOL FIFO ECC error counters */
+#define XCAN_ECC_CFG_REECTXTL_MASK BIT(0) /* Reset TXTL FIFO ECC error counters */
+#define XCAN_ECC_1BIT_CNT_MASK GENMASK(15, 0) /* FIFO ECC 1bit count mask */
+#define XCAN_ECC_2BIT_CNT_MASK GENMASK(31, 16) /* FIFO ECC 2bit count mask */

/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
#define XCAN_BRPR_TDC_ENABLE BIT(16) /* Transmitter Delay Compensation (TDC) Enable */
@@ -202,6 +227,13 @@ struct xcan_devtype_data {
* @devtype: Device type specific constants
* @transceiver: Optional pointer to associated CAN transceiver
* @rstc: Pointer to reset control
+ * @ecc_enable: ECC enable flag
+ * @ecc_2bit_rxfifo_cnt: RXFIFO 2bit ECC count
+ * @ecc_1bit_rxfifo_cnt: RXFIFO 1bit ECC count
+ * @ecc_2bit_txolfifo_cnt: TXOLFIFO 2bit ECC count
+ * @ecc_1bit_txolfifo_cnt: TXOLFIFO 1bit ECC count
+ * @ecc_2bit_txtlfifo_cnt: TXTLFIFO 2bit ECC count
+ * @ecc_1bit_txtlfifo_cnt: TXTLFIFO 1bit ECC count
*/
struct xcan_priv {
struct can_priv can;
@@ -221,6 +253,13 @@ struct xcan_priv {
struct xcan_devtype_data devtype;
struct phy *transceiver;
struct reset_control *rstc;
+ bool ecc_enable;
+ u64_stats_t ecc_2bit_rxfifo_cnt;
+ u64_stats_t ecc_1bit_rxfifo_cnt;
+ u64_stats_t ecc_2bit_txolfifo_cnt;
+ u64_stats_t ecc_1bit_txolfifo_cnt;
+ u64_stats_t ecc_2bit_txtlfifo_cnt;
+ u64_stats_t ecc_1bit_txtlfifo_cnt;
};

/* CAN Bittiming constants as per Xilinx CAN specs */
@@ -523,6 +562,9 @@ static int xcan_chip_start(struct net_device *ndev)
XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
XCAN_IXR_ARBLST_MASK | xcan_rx_int_mask(priv);

+ if (priv->ecc_enable)
+ ier |= XCAN_IXR_ECC_MASK;
+
if (priv->devtype.flags & XCAN_FLAG_RXMNF)
ier |= XCAN_IXR_RXMNF_MASK;

@@ -1127,6 +1169,50 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
priv->can.can_stats.bus_error++;
}

+ if (priv->ecc_enable && isr & XCAN_IXR_ECC_MASK) {
+ u32 reg_rx_ecc, reg_txol_ecc, reg_txtl_ecc;
+
+ reg_rx_ecc = priv->read_reg(priv, XCAN_RXFIFO_ECC_OFFSET);
+ reg_txol_ecc = priv->read_reg(priv, XCAN_TXOLFIFO_ECC_OFFSET);
+ reg_txtl_ecc = priv->read_reg(priv, XCAN_TXTLFIFO_ECC_OFFSET);
+
+ /* The counter reaches its maximum at 0xffff and does not overflow.
+ * Accept the small race window between reading and resetting ECC counters.
+ */
+ priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
+ XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);
+
+ if (isr & XCAN_IXR_E2BERX_MASK) {
+ u64_stats_add(&priv->ecc_2bit_rxfifo_cnt,
+ FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_rx_ecc));
+ }
+
+ if (isr & XCAN_IXR_E1BERX_MASK) {
+ u64_stats_add(&priv->ecc_1bit_rxfifo_cnt,
+ FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_rx_ecc));
+ }
+
+ if (isr & XCAN_IXR_E2BETXOL_MASK) {
+ u64_stats_add(&priv->ecc_2bit_txolfifo_cnt,
+ FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txol_ecc));
+ }
+
+ if (isr & XCAN_IXR_E1BETXOL_MASK) {
+ u64_stats_add(&priv->ecc_1bit_txolfifo_cnt,
+ FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txol_ecc));
+ }
+
+ if (isr & XCAN_IXR_E2BETXTL_MASK) {
+ u64_stats_add(&priv->ecc_2bit_txtlfifo_cnt,
+ FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txtl_ecc));
+ }
+
+ if (isr & XCAN_IXR_E1BETXTL_MASK) {
+ u64_stats_add(&priv->ecc_1bit_txtlfifo_cnt,
+ FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txtl_ecc));
+ }
+ }
+
if (cf.can_id) {
struct can_frame *skb_cf;
struct sk_buff *skb = alloc_can_err_skb(ndev, &skb_cf);
@@ -1355,7 +1441,7 @@ static irqreturn_t xcan_interrupt(int irq, void *dev_id)
struct net_device *ndev = (struct net_device *)dev_id;
struct xcan_priv *priv = netdev_priv(ndev);
u32 isr, ier;
- u32 isr_errors;
+ u32 isr_errors, mask;
u32 rx_int_mask = xcan_rx_int_mask(priv);

/* Get the interrupt status from Xilinx CAN */
@@ -1374,10 +1460,15 @@ static irqreturn_t xcan_interrupt(int irq, void *dev_id)
if (isr & XCAN_IXR_TXOK_MASK)
xcan_tx_interrupt(ndev, isr);

+ mask = XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
+ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK |
+ XCAN_IXR_RXMNF_MASK;
+
+ if (priv->ecc_enable)
+ mask |= XCAN_IXR_ECC_MASK;
+
/* Check for the type of error interrupt and Processing it */
- isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
- XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK |
- XCAN_IXR_RXMNF_MASK);
+ isr_errors = isr & mask;
if (isr_errors) {
priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors);
xcan_err_interrupt(ndev, isr);
@@ -1796,6 +1887,7 @@ static int xcan_probe(struct platform_device *pdev)
return -ENOMEM;

priv = netdev_priv(ndev);
+ priv->ecc_enable = of_property_read_bool(pdev->dev.of_node, "xlnx,has-ecc");
priv->dev = &pdev->dev;
priv->can.bittiming_const = devtype->bittiming_const;
priv->can.do_set_mode = xcan_do_set_mode;
@@ -1912,6 +2004,11 @@ static int xcan_probe(struct platform_device *pdev)
priv->reg_base, ndev->irq, priv->can.clock.freq,
hw_tx_max, priv->tx_max);

+ if (priv->ecc_enable) {
+ /* Reset FIFO ECC counters */
+ priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
+ XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);
+ }
return 0;

err_disableclks:
--
2.1.1


2024-01-12 11:42:24

by Goud, Srinivas

[permalink] [raw]
Subject: [PATCH RESEND v7 3/3] can: xilinx_can: Add ethtool stats interface for ECC errors

Add ethtool stats interface for reading FIFO 1bit/2bit ECC errors information.

Signed-off-by: Srinivas Goud <[email protected]>
---
Changes in v7:
Update with spinlock only for stats counters

Changes in v6:
None

Changes in v5:
Address review comments
Add get_strings and get_sset_count stats interface
Use u64 stats helper function

Changes in v4:
None

Changes in v3:
None

Changes in v2:
Add ethtool stats interface

drivers/net/can/xilinx_can.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index c8691a1..80b0586 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -228,6 +228,7 @@ struct xcan_devtype_data {
* @transceiver: Optional pointer to associated CAN transceiver
* @rstc: Pointer to reset control
* @ecc_enable: ECC enable flag
+ * @stats_lock: Lock for synchronizing ECC errors stats
* @ecc_2bit_rxfifo_cnt: RXFIFO 2bit ECC count
* @ecc_1bit_rxfifo_cnt: RXFIFO 1bit ECC count
* @ecc_2bit_txolfifo_cnt: TXOLFIFO 2bit ECC count
@@ -254,6 +255,7 @@ struct xcan_priv {
struct phy *transceiver;
struct reset_control *rstc;
bool ecc_enable;
+ spinlock_t stats_lock; /* Lock for synchronizing ECC errors stats */
u64_stats_t ecc_2bit_rxfifo_cnt;
u64_stats_t ecc_1bit_rxfifo_cnt;
u64_stats_t ecc_2bit_txolfifo_cnt;
@@ -347,6 +349,12 @@ static const struct can_tdc_const xcan_tdc_const_canfd2 = {
.tdcf_max = 0,
};

+static const char xcan_priv_flags_strings[][ETH_GSTRING_LEN] = {
+ "err-ecc-rx-2-bit", "err-ecc-rx-1-bit",
+ "err-ecc-txol-2-bit", "err-ecc-txol-1-bit",
+ "err-ecc-txtl-2-bit", "err-ecc-txtl-1-bit",
+};
+
/**
* xcan_write_reg_le - Write a value to the device register little endian
* @priv: Driver private data structure
@@ -1171,6 +1179,7 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)

if (priv->ecc_enable && isr & XCAN_IXR_ECC_MASK) {
u32 reg_rx_ecc, reg_txol_ecc, reg_txtl_ecc;
+ unsigned long flags;

reg_rx_ecc = priv->read_reg(priv, XCAN_RXFIFO_ECC_OFFSET);
reg_txol_ecc = priv->read_reg(priv, XCAN_TXOLFIFO_ECC_OFFSET);
@@ -1182,6 +1191,8 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);

+ spin_lock_irqsave(&priv->stats_lock, flags);
+
if (isr & XCAN_IXR_E2BERX_MASK) {
u64_stats_add(&priv->ecc_2bit_rxfifo_cnt,
FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_rx_ecc));
@@ -1211,6 +1222,8 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
u64_stats_add(&priv->ecc_1bit_txtlfifo_cnt,
FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txtl_ecc));
}
+
+ spin_unlock_irqrestore(&priv->stats_lock, flags);
}

if (cf.can_id) {
@@ -1637,6 +1650,44 @@ static int xcan_get_auto_tdcv(const struct net_device *ndev, u32 *tdcv)
return 0;
}

+static void xcan_get_strings(struct net_device *ndev, u32 stringset, u8 *buf)
+{
+ switch (stringset) {
+ case ETH_SS_STATS:
+ memcpy(buf, &xcan_priv_flags_strings,
+ sizeof(xcan_priv_flags_strings));
+ }
+}
+
+static int xcan_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(xcan_priv_flags_strings);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void xcan_get_ethtool_stats(struct net_device *ndev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ unsigned long flags;
+ int i = 0;
+
+ spin_lock_irqsave(&priv->stats_lock, flags);
+
+ data[i++] = u64_stats_read(&priv->ecc_2bit_rxfifo_cnt);
+ data[i++] = u64_stats_read(&priv->ecc_1bit_rxfifo_cnt);
+ data[i++] = u64_stats_read(&priv->ecc_2bit_txolfifo_cnt);
+ data[i++] = u64_stats_read(&priv->ecc_1bit_txolfifo_cnt);
+ data[i++] = u64_stats_read(&priv->ecc_2bit_txtlfifo_cnt);
+ data[i++] = u64_stats_read(&priv->ecc_1bit_txtlfifo_cnt);
+
+ spin_unlock_irqrestore(&priv->stats_lock, flags);
+}
+
static const struct net_device_ops xcan_netdev_ops = {
.ndo_open = xcan_open,
.ndo_stop = xcan_close,
@@ -1646,6 +1697,9 @@ static const struct net_device_ops xcan_netdev_ops = {

static const struct ethtool_ops xcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
+ .get_strings = xcan_get_strings,
+ .get_sset_count = xcan_get_sset_count,
+ .get_ethtool_stats = xcan_get_ethtool_stats,
};

/**
--
2.1.1


2024-02-13 10:36:36

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v7 0/3] can: xilinx_can: Add ECC feature support

On 12.01.2024 17:07:30, Srinivas Goud wrote:
> Add ECC feature support to Tx and Rx FIFOs for Xilinx CAN Controller.
> ECC is an IP configuration option where counter registers are added in
> IP for 1bit/2bit ECC errors count and reset.
> Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
> interrupts.
>
> Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
> to support ECC if the ECC block is enabled in the HW.
>
> Add ethtool stats interface for getting all the ECC errors information.
>
> There is no public documentation for it available.

Lately I was using ethtool based stats, too and figured out, there's no
need for a spinlock, you can use a struct u64_stats_sync,
u64_stats_update_begin(), u64_stats_update_end(), and
u64_stats_fetch_retry() instead. These are no-ops on 64 bit systems and
sequential locks on 32 bit systems.

I'll send a v8.

regards,
Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (1.17 kB)
signature.asc (499.00 B)
Download all attachments

2024-02-13 11:00:50

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v7 0/3] can: xilinx_can: Add ECC feature support

On 13.02.2024 11:22:49, Marc Kleine-Budde wrote:
> On 12.01.2024 17:07:30, Srinivas Goud wrote:
> > Add ECC feature support to Tx and Rx FIFOs for Xilinx CAN Controller.
> > ECC is an IP configuration option where counter registers are added in
> > IP for 1bit/2bit ECC errors count and reset.
> > Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
> > interrupts.
> >
> > Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
> > to support ECC if the ECC block is enabled in the HW.
> >
> > Add ethtool stats interface for getting all the ECC errors information.
> >
> > There is no public documentation for it available.
>
> Lately I was using ethtool based stats, too and figured out, there's no
> need for a spinlock, you can use a struct u64_stats_sync,
> u64_stats_update_begin(), u64_stats_update_end(), and
> u64_stats_fetch_retry() instead. These are no-ops on 64 bit systems and
> sequential locks on 32 bit systems.
>
> I'll send a v8.

https://lore.kernel.org/all/[email protected]/

Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (1.33 kB)
signature.asc (499.00 B)
Download all attachments