can: add CAN_ERR_CNT flag to notify availability of error counter
authorVincent Mailhol <mailhol.vincent@wanadoo.fr>
Tue, 19 Jul 2022 14:35:49 +0000 (23:35 +0900)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Wed, 20 Jul 2022 07:27:37 +0000 (09:27 +0200)
Add a dedicated flag in uapi/linux/can/error.h to notify the userland
that fields data[6] and data[7] of the CAN error frame were
respectively populated with the tx and rx error counters.

For all driver tree-wide, set up this flags whenever needed.

Link: https://lore.kernel.org/all/20220719143550.3681-12-mailhol.vincent@wanadoo.fr
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
25 files changed:
drivers/net/can/c_can/c_can_main.c
drivers/net/can/cc770/cc770.c
drivers/net/can/ctucanfd/ctucanfd_base.c
drivers/net/can/grcan.c
drivers/net/can/ifi_canfd/ifi_canfd.c
drivers/net/can/janz-ican3.c
drivers/net/can/kvaser_pciefd.c
drivers/net/can/m_can/m_can.c
drivers/net/can/pch_can.c
drivers/net/can/peak_canfd/peak_canfd.c
drivers/net/can/rcar/rcar_can.c
drivers/net/can/rcar/rcar_canfd.c
drivers/net/can/sja1000/sja1000.c
drivers/net/can/slcan/slcan-core.c
drivers/net/can/spi/hi311x.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
drivers/net/can/sun4i_can.c
drivers/net/can/ti_hecc.c
drivers/net/can/usb/esd_usb.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
drivers/net/can/usb/peak_usb/pcan_usb.c
drivers/net/can/usb/usb_8dev.c
drivers/net/can/xilinx_can.c
include/uapi/linux/can/error.h

index ed4db4c..de38d8f 100644 (file)
@@ -952,14 +952,14 @@ static int c_can_handle_state_change(struct net_device *dev,
 
        switch (error_type) {
        case C_CAN_NO_ERROR:
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = CAN_ERR_CRTL_ACTIVE;
                cf->data[6] = bec.txerr;
                cf->data[7] = bec.rxerr;
                break;
        case C_CAN_ERROR_WARNING:
                /* error warning state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = (bec.txerr > bec.rxerr) ?
                        CAN_ERR_CRTL_TX_WARNING :
                        CAN_ERR_CRTL_RX_WARNING;
@@ -969,7 +969,7 @@ static int c_can_handle_state_change(struct net_device *dev,
                break;
        case C_CAN_ERROR_PASSIVE:
                /* error passive state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                if (rx_err_passive)
                        cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
                if (bec.txerr > 127)
index bb7224c..797a954 100644 (file)
@@ -512,6 +512,7 @@ static int cc770_err(struct net_device *dev, u8 status)
 
        /* Use extended functions of the CC770 */
        if (priv->control_normal_mode & CTRL_EAF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = cc770_read_reg(priv, tx_error_counter);
                cf->data[7] = cc770_read_reg(priv, rx_error_counter);
        }
index 14ac7c0..6b281f6 100644 (file)
@@ -847,7 +847,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
                case CAN_STATE_ERROR_PASSIVE:
                        priv->can.can_stats.error_passive++;
                        if (skb) {
-                               cf->can_id |= CAN_ERR_CRTL;
+                               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                                cf->data[1] = (bec.rxerr > 127) ?
                                                CAN_ERR_CRTL_RX_PASSIVE :
                                                CAN_ERR_CRTL_TX_PASSIVE;
@@ -858,7 +858,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
                case CAN_STATE_ERROR_WARNING:
                        priv->can.can_stats.error_warning++;
                        if (skb) {
-                               cf->can_id |= CAN_ERR_CRTL;
+                               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                                cf->data[1] |= (bec.txerr > bec.rxerr) ?
                                        CAN_ERR_CRTL_TX_WARNING :
                                        CAN_ERR_CRTL_RX_WARNING;
@@ -867,6 +867,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
                        }
                        break;
                case CAN_STATE_ERROR_ACTIVE:
+                       cf->can_id |= CAN_ERR_CNT;
                        cf->data[1] = CAN_ERR_CRTL_ACTIVE;
                        cf->data[6] = bec.txerr;
                        cf->data[7] = bec.rxerr;
index 4c47c10..24035a6 100644 (file)
@@ -671,6 +671,7 @@ static void grcan_err(struct net_device *dev, u32 sources, u32 status)
                                /* There are no others at this point */
                                break;
                        }
+                       cf.can_id |= CAN_ERR_CNT;
                        cf.data[6] = txerr;
                        cf.data[7] = rxerr;
                        priv->can.state = state;
index 968ed6d..64e3be8 100644 (file)
@@ -492,7 +492,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
        switch (new_state) {
        case CAN_STATE_ERROR_WARNING:
                /* error warning state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = (bec.txerr > bec.rxerr) ?
                        CAN_ERR_CRTL_TX_WARNING :
                        CAN_ERR_CRTL_RX_WARNING;
@@ -501,7 +501,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
                break;
        case CAN_STATE_ERROR_PASSIVE:
                /* error passive state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
                if (bec.txerr > 127)
                        cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
index 35bfb82..ccb5c54 100644 (file)
@@ -1127,7 +1127,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
        /* bus error interrupt */
        if (isrc == CEVTIND_BEI) {
                mod->can.can_stats.bus_error++;
-               cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+               cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
 
                switch (ecc & ECC_MASK) {
                case ECC_BIT:
@@ -1153,7 +1153,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
 
        if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING ||
                                        state == CAN_STATE_ERROR_PASSIVE)) {
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                if (state == CAN_STATE_ERROR_WARNING) {
                        mod->can.can_stats.error_warning++;
                        cf->data[1] = (txerr > rxerr) ?
index 017f2d3..dcd2c9d 100644 (file)
@@ -1306,7 +1306,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
        shhwtstamps->hwtstamp =
                ns_to_ktime(div_u64(p->timestamp * 1000,
                                    can->kv_pcie->freq_to_ticks_div));
-       cf->can_id |= CAN_ERR_BUSERROR;
+       cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
 
        cf->data[6] = bec.txerr;
        cf->data[7] = bec.rxerr;
index afaaeb6..713a4b0 100644 (file)
@@ -741,7 +741,7 @@ static int m_can_handle_state_change(struct net_device *dev,
        switch (new_state) {
        case CAN_STATE_ERROR_WARNING:
                /* error warning state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = (bec.txerr > bec.rxerr) ?
                        CAN_ERR_CRTL_TX_WARNING :
                        CAN_ERR_CRTL_RX_WARNING;
@@ -750,7 +750,7 @@ static int m_can_handle_state_change(struct net_device *dev,
                break;
        case CAN_STATE_ERROR_PASSIVE:
                /* error passive state */
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                ecr = m_can_read(cdev, M_CAN_ECR);
                if (ecr & ECR_RP)
                        cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
index 497ef77..50f6719 100644 (file)
@@ -497,6 +497,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
                priv->can.can_stats.bus_off++;
                can_bus_off(ndev);
        } else {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = errc & PCH_TEC;
                cf->data[7] = (errc & PCH_REC) >> 8;
        }
index b2dea36..afb9adb 100644 (file)
@@ -373,7 +373,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
                priv->can.state = CAN_STATE_ERROR_PASSIVE;
                priv->can.can_stats.error_passive++;
                if (skb) {
-                       cf->can_id |= CAN_ERR_CRTL;
+                       cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                        cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
                                        CAN_ERR_CRTL_TX_PASSIVE :
                                        CAN_ERR_CRTL_RX_PASSIVE;
@@ -386,7 +386,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
                priv->can.state = CAN_STATE_ERROR_WARNING;
                priv->can.can_stats.error_warning++;
                if (skb) {
-                       cf->can_id |= CAN_ERR_CRTL;
+                       cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                        cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
                                        CAN_ERR_CRTL_TX_WARNING :
                                        CAN_ERR_CRTL_RX_WARNING;
@@ -430,7 +430,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
                return -ENOMEM;
        }
 
-       cf->can_id |= CAN_ERR_CRTL;
+       cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
        cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 
        cf->data[6] = priv->bec.txerr;
index 24d7a71..d11db21 100644 (file)
@@ -334,6 +334,7 @@ static void rcar_can_error(struct net_device *ndev)
                if (skb)
                        cf->can_id |= CAN_ERR_BUSOFF;
        } else if (skb) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index ba42cef..e338228 100644 (file)
@@ -1052,7 +1052,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
                netdev_dbg(ndev, "Error warning interrupt\n");
                priv->can.state = CAN_STATE_ERROR_WARNING;
                priv->can.can_stats.error_warning++;
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING :
                        CAN_ERR_CRTL_RX_WARNING;
                cf->data[6] = txerr;
@@ -1062,7 +1062,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
                netdev_dbg(ndev, "Error passive interrupt\n");
                priv->can.state = CAN_STATE_ERROR_PASSIVE;
                priv->can.can_stats.error_passive++;
-               cf->can_id |= CAN_ERR_CRTL;
+               cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
                cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE :
                        CAN_ERR_CRTL_RX_PASSIVE;
                cf->data[6] = txerr;
index 74bff50..75a2f9b 100644 (file)
@@ -426,6 +426,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
                        state = CAN_STATE_ERROR_ACTIVE;
        }
        if (state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index dfd1bab..dc28e71 100644 (file)
@@ -314,6 +314,7 @@ static void slc_bump_state(struct slcan *sl)
        if (state == CAN_STATE_BUS_OFF) {
                can_bus_off(dev);
        } else if (skb) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index bfb7c4b..167114a 100644 (file)
@@ -680,6 +680,7 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
                                        break;
                                }
                        } else {
+                               cf->can_id |= CAN_ERR_CNT;
                                cf->data[6] = txerr;
                                cf->data[7] = rxerr;
                        }
index 9b47b07..f4e174c 100644 (file)
@@ -1099,6 +1099,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
                err = mcp251xfd_get_berr_counter(priv->ndev, &bec);
                if (err)
                        return err;
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = bec.txerr;
                cf->data[7] = bec.rxerr;
        }
index afe9b54..b90dfb4 100644 (file)
@@ -566,6 +566,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
                        state = CAN_STATE_ERROR_ACTIVE;
        }
        if (skb && state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index debe17b..afa3877 100644 (file)
@@ -662,6 +662,7 @@ static void ti_hecc_change_state(struct net_device *ndev,
        can_change_state(priv->ndev, cf, tx_state, rx_state);
 
        if (max(tx_state, rx_state) != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = hecc_read(priv, HECC_CANTEC);
                cf->data[7] = hecc_read(priv, HECC_CANREC);
        }
index 8a4bf29..177ed33 100644 (file)
@@ -265,7 +265,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
                        priv->can.can_stats.bus_error++;
                        stats->rx_errors++;
 
-                       cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+                       cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR |
+                                     CAN_ERR_CNT;
 
                        switch (ecc & SJA1000_ECC_MASK) {
                        case SJA1000_ECC_BIT:
index 4040934..dd65c10 100644 (file)
@@ -918,6 +918,7 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
                priv->can.can_stats.restarts++;
 
        if (new_state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = bec->txerr;
                cf->data[7] = bec->rxerr;
        }
@@ -1072,6 +1073,7 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
 
        cf->can_id |= CAN_ERR_BUSERROR;
        if (new_state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = bec.txerr;
                cf->data[7] = bec.rxerr;
        }
index f551fde..07f687f 100644 (file)
@@ -854,6 +854,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
        }
 
        if (new_state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = es->txerr;
                cf->data[7] = es->rxerr;
        }
index 091c631..d07b7ee 100644 (file)
@@ -506,6 +506,7 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
                        /* Supply TX/RX error counters in case of
                         * controller error.
                         */
+                       cf->can_id = CAN_ERR_CNT;
                        cf->data[6] = mc->pdev->bec.txerr;
                        cf->data[7] = mc->pdev->bec.rxerr;
                }
index 4d38dc9..8b7cd69 100644 (file)
@@ -439,6 +439,7 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
        if (rx_errors)
                stats->rx_errors++;
        if (priv->can.state != CAN_STATE_BUS_OFF) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index 0de2f97..caa6b4c 100644 (file)
@@ -965,6 +965,7 @@ static void xcan_set_error_state(struct net_device *ndev,
        can_change_state(ndev, cf, tx_state, rx_state);
 
        if (cf) {
+               cf->can_id |= CAN_ERR_CNT;
                cf->data[6] = txerr;
                cf->data[7] = rxerr;
        }
index a1000cb..b7c3efd 100644 (file)
@@ -57,6 +57,8 @@
 #define CAN_ERR_BUSOFF       0x00000040U /* bus off */
 #define CAN_ERR_BUSERROR     0x00000080U /* bus error (may flood!) */
 #define CAN_ERR_RESTARTED    0x00000100U /* controller restarted */
+#define CAN_ERR_CNT          0x00000200U /* TX error counter / data[6] */
+                                        /* RX error counter / data[7] */
 
 /* arbitration lost in bit ... / data[0] */
 #define CAN_ERR_LOSTARB_UNSPEC   0x00 /* unspecified */