can: mcp25xxfd: mcp25xxfd_handle_eccif(): add ECC related errata and update log messages
authorThomas Kopp <thomas.kopp@microchip.com>
Fri, 25 Sep 2020 06:56:06 +0000 (08:56 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Wed, 30 Sep 2020 08:34:30 +0000 (10:34 +0200)
This patch adds a reference to the recent released MCP2517FD and MCP2518FD
errata sheets and paste the explanation.

The single error correction does not always work, so always indicate that a
single error occurred. If the location of the ECC error is outside of the
TX-RAM always use netdev_notice() to log the problem. For ECC errors in the
TX-RAM, there is a recovery procedure.

Signed-off-by: Thomas Kopp <thomas.kopp@microchip.com>
Link: https://lore.kernel.org/r/20200925065606.358-1-thomas.kopp@microchip.com
[mkl: split into two patches, adjust subject and commit message]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/spi/mcp25xxfd/mcp25xxfd-core.c

index bd2ba98..106dda8 100644 (file)
@@ -1973,8 +1973,20 @@ mcp25xxfd_handle_eccif(struct mcp25xxfd_priv *priv, bool set_normal_mode)
        else
                return err;
 
+       /* Errata Reference:
+        * mcp2517fd: DS80000789B, mcp2518fd: DS80000792C 2.
+        *
+        * ECC single error correction does not work in all cases:
+        *
+        * Fix/Work Around:
+        * Enable single error correction and double error detection
+        * interrupts by setting SECIE and DEDIE. Handle SECIF as a
+        * detection interrupt and do not rely on the error
+        * correction. Instead, handle both interrupts as a
+        * notification that the RAM word at ERRADDR was corrupted.
+        */
        if (ecc_stat & MCP25XXFD_REG_ECCSTAT_SECIF)
-               msg = "Single ECC Error corrected at address";
+               msg = "Single ECC Error detected at address";
        else if (ecc_stat & MCP25XXFD_REG_ECCSTAT_DEDIF)
                msg = "Double ECC Error detected at address";
        else
@@ -1983,12 +1995,7 @@ mcp25xxfd_handle_eccif(struct mcp25xxfd_priv *priv, bool set_normal_mode)
        if (!in_tx_ram) {
                ecc->ecc_stat = 0;
 
-               if (ecc_stat & MCP25XXFD_REG_ECCSTAT_SECIF)
-                       netdev_info(priv->ndev, "%s 0x%04x.\n",
-                                   msg, addr);
-               else
-                       netdev_notice(priv->ndev, "%s 0x%04x.\n",
-                                     msg, addr);
+               netdev_notice(priv->ndev, "%s 0x%04x.\n", msg, addr);
        } else {
                /* Re-occurring error? */
                if (ecc->ecc_stat == ecc_stat) {