Linux CAN drivers development
 help / color / mirror / Atom feed
* [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics
@ 2024-11-22 22:15 Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 01/12] can: c_can: update statistics if skb allocation fails Dario Binacchi
                   ` (13 more replies)
  0 siblings, 14 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Akshay Bhat,
	Chandrasekar Ramakrishnan, Chen-Yu Tsai, David S. Miller,
	Dong Aisheng, Fengguang Wu, Gerhard Bertelsmann, Jernej Skrabec,
	Ji-Ze Hong (Peter Hong), Krzysztof Kozlowski, Marc Kleine-Budde,
	Marek Vasut, Maxime Ripard, Oliver Hartkopp, Samuel Holland,
	Sebastian Haas, Uwe Kleine-König, Varka Bhadram,
	Vincent Mailhol, Wolfgang Grandegger, linux-arm-kernel, linux-can,
	linux-sunxi

This series extends the patch 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics"),
already merged into the mainline, to other CAN devices that similarly do
not correctly increment the error counters for reception/transmission.

Changes in v2:
- Fix patches 7 through 12 to ensure that statistics are updated even
  if the allocation of skb fails.
- Add five new patches (i. e. 1-5), created during the further analysis
  of the code while correcting patches from the v1 series (i. e. 7-12).

Dario Binacchi (12):
  can: c_can: update statistics if skb allocation fails
  can: sun4i_can: call can_change_state() even if cf is NULL
  can: sun4i_can: continue to use likely() to check skb
  can: hi311x: fix txerr and rxerr reporting
  can: hi311x: update state error statistics if skb allocation fails
  can: m_can: fix {rx,tx}_errors statistics
  can: ifi_canfd: fix {rx,tx}_errors statistics
  can: hi311x: fix {rx,tx}_errors statistics
  can: sja1000: fix {rx,tx}_errors statistics
  can: sun4i_can: fix {rx,tx}_errors statistics
  can: ems_usb: fix {rx,tx}_errors statistics
  can: f81604: fix {rx,tx}_errors statistics

 drivers/net/can/c_can/c_can_main.c    | 26 +++++++----
 drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++-------
 drivers/net/can/m_can/m_can.c         | 33 +++++++++----
 drivers/net/can/sja1000/sja1000.c     | 67 ++++++++++++++++-----------
 drivers/net/can/spi/hi311x.c          | 55 +++++++++++++---------
 drivers/net/can/sun4i_can.c           | 21 +++++----
 drivers/net/can/usb/ems_usb.c         | 58 +++++++++++++----------
 drivers/net/can/usb/f81604.c          | 10 ++--
 8 files changed, 205 insertions(+), 123 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 01/12] can: c_can: update statistics if skb allocation fails
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 02/12] can: sun4i_can: call can_change_state() even if cf is NULL Dario Binacchi
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Marc Kleine-Budde, Vincent Mailhol,
	linux-can

This patch ensures that the statistics are always updated, even if the
skb allocation fails.

Fixes: 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Added in v2

 drivers/net/can/c_can/c_can_main.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
index 511615dc3341..cc371d0c9f3c 100644
--- a/drivers/net/can/c_can/c_can_main.c
+++ b/drivers/net/can/c_can/c_can_main.c
@@ -1014,49 +1014,57 @@ static int c_can_handle_bus_err(struct net_device *dev,
 
 	/* propagate the error condition to the CAN stack */
 	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* check for 'last error code' which tells us the
 	 * type of the last error to occur on the CAN bus
 	 */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	switch (lec_type) {
 	case LEC_STUFF_ERROR:
 		netdev_dbg(dev, "stuff error\n");
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
 		stats->rx_errors++;
 		break;
 	case LEC_FORM_ERROR:
 		netdev_dbg(dev, "form error\n");
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
 		stats->rx_errors++;
 		break;
 	case LEC_ACK_ERROR:
 		netdev_dbg(dev, "ack error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
 		stats->tx_errors++;
 		break;
 	case LEC_BIT1_ERROR:
 		netdev_dbg(dev, "bit1 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
 		stats->tx_errors++;
 		break;
 	case LEC_BIT0_ERROR:
 		netdev_dbg(dev, "bit0 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
 		stats->tx_errors++;
 		break;
 	case LEC_CRC_ERROR:
 		netdev_dbg(dev, "CRC error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
 		stats->rx_errors++;
 		break;
 	default:
 		break;
 	}
 
+	if (unlikely(!skb))
+		return 0;
+
 	netif_receive_skb(skb);
 	return 1;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 02/12] can: sun4i_can: call can_change_state() even if cf is NULL
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 01/12] can: c_can: update statistics if skb allocation fails Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb Dario Binacchi
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Chen-Yu Tsai, Gerhard Bertelsmann,
	Jernej Skrabec, Marc Kleine-Budde, Maxime Ripard, Samuel Holland,
	Vincent Mailhol, linux-arm-kernel, linux-can, linux-sunxi

The function can_change_state() can also be called if the allocation
of the skb fails, as it handles the cf parameter when it is null.
Additionally, this ensures that the statistics related to state error
counters (i. e. warning, passive, and bus-off) are updated.

Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Added in v2

 drivers/net/can/sun4i_can.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 360158c295d3..17f94cca93fb 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -629,10 +629,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
 		tx_state = txerr >= rxerr ? state : 0;
 		rx_state = txerr <= rxerr ? state : 0;
 
-		if (likely(skb))
-			can_change_state(dev, cf, tx_state, rx_state);
-		else
-			priv->can.state = state;
+		/* The skb allocation might fail, but can_change_state()
+		 * handles cf == NULL.
+		 */
+		can_change_state(dev, cf, tx_state, rx_state);
 		if (state == CAN_STATE_BUS_OFF)
 			can_bus_off(dev);
 	}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 01/12] can: c_can: update statistics if skb allocation fails Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 02/12] can: sun4i_can: call can_change_state() even if cf is NULL Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-26  9:18   ` Marc Kleine-Budde
  2024-11-22 22:15 ` [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting Dario Binacchi
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Chen-Yu Tsai, Jernej Skrabec,
	Marc Kleine-Budde, Samuel Holland, Vincent Mailhol,
	linux-arm-kernel, linux-can, linux-sunxi

Throughout the sun4i_can_err() function, the likely() macro is used to
check the skb buffer, except in one instance. This patch makes the code
consistent by using the macro in that case as well.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Added in v2

 drivers/net/can/sun4i_can.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 17f94cca93fb..840b972498c1 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -570,7 +570,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
 		else
 			state = CAN_STATE_ERROR_ACTIVE;
 	}
-	if (skb && state != CAN_STATE_BUS_OFF) {
+	if (likely(skb) && state != CAN_STATE_BUS_OFF) {
 		cf->can_id |= CAN_ERR_CNT;
 		cf->data[6] = txerr;
 		cf->data[7] = rxerr;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (2 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-26  9:48   ` Marc Kleine-Budde
  2024-11-22 22:15 ` [PATCH v2 05/12] can: hi311x: update state error statistics if skb allocation fails Dario Binacchi
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Krzysztof Kozlowski,
	Marc Kleine-Budde, Vincent Mailhol, linux-can

The commit a22bd630cfff ("can: hi311x: do not report txerr and rxerr
during bus-off") removed the reporting of rxerr and txerr even in case
of correct operation (i. e. not bus-off). The CAN frame is unnecessarily
set since netif_rx() has already been called. The patch fixes the issue
by postponing the netif_rx() call in case of txerr and rxerr reporting.

Fixes: a22bd630cfff ("can: hi311x: do not report txerr and rxerr during bus-off")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Added in v2

 drivers/net/can/spi/hi311x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 148d974ebb21..b67464df25ff 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -671,9 +671,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
 			tx_state = txerr >= rxerr ? new_state : 0;
 			rx_state = txerr <= rxerr ? new_state : 0;
 			can_change_state(net, cf, tx_state, rx_state);
-			netif_rx(skb);
 
 			if (new_state == CAN_STATE_BUS_OFF) {
+				netif_rx(skb);
 				can_bus_off(net);
 				if (priv->can.restart_ms == 0) {
 					priv->force_quit = 1;
@@ -684,6 +684,7 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
 				cf->can_id |= CAN_ERR_CNT;
 				cf->data[6] = txerr;
 				cf->data[7] = rxerr;
+				netif_rx(skb);
 			}
 		}
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 05/12] can: hi311x: update state error statistics if skb allocation fails
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (3 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 06/12] can: m_can: fix {rx,tx}_errors statistics Dario Binacchi
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Krzysztof Kozlowski,
	Marc Kleine-Budde, Vincent Mailhol, linux-can

This patch ensures that the statistics related to state error counters
(i. e. warning, passive, and bus-off) are updated even in case the skb
allocation fails. Additionally, the bus-off state is now also handled.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Added in v2

 drivers/net/can/spi/hi311x.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index b67464df25ff..25d9b32f5701 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -663,8 +663,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
 			u8 rxerr, txerr;
 
 			skb = alloc_can_err_skb(net, &cf);
-			if (!skb)
-				break;
 
 			txerr = hi3110_read(spi, HI3110_READ_TEC);
 			rxerr = hi3110_read(spi, HI3110_READ_REC);
@@ -673,14 +671,15 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
 			can_change_state(net, cf, tx_state, rx_state);
 
 			if (new_state == CAN_STATE_BUS_OFF) {
-				netif_rx(skb);
+				if (skb)
+					netif_rx(skb);
 				can_bus_off(net);
 				if (priv->can.restart_ms == 0) {
 					priv->force_quit = 1;
 					hi3110_hw_sleep(spi);
 					break;
 				}
-			} else {
+			} else if (skb) {
 				cf->can_id |= CAN_ERR_CNT;
 				cf->data[6] = txerr;
 				cf->data[7] = rxerr;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 06/12] can: m_can: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (4 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 05/12] can: hi311x: update state error statistics if skb allocation fails Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 07/12] can: ifi_canfd: " Dario Binacchi
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Chandrasekar Ramakrishnan,
	Dong Aisheng, Fengguang Wu, Marc Kleine-Budde, Varka Bhadram,
	Vincent Mailhol, linux-can

The m_can_handle_lec_err() function was incorrectly incrementing only the
receive error counter, even in cases of bit or acknowledgment errors that
occur during transmission. The patch fixes the issue by incrementing the
appropriate counter based on the type of error.

Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 16e9e7d7527d..533bcb77c9f9 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -695,47 +695,60 @@ static int m_can_handle_lec_err(struct net_device *dev,
 	u32 timestamp = 0;
 
 	cdev->can.can_stats.bus_error++;
-	stats->rx_errors++;
 
 	/* propagate the error condition to the CAN stack */
 	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* check for 'last error code' which tells us the
 	 * type of the last error to occur on the CAN bus
 	 */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	switch (lec_type) {
 	case LEC_STUFF_ERROR:
 		netdev_dbg(dev, "stuff error\n");
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
 		break;
 	case LEC_FORM_ERROR:
 		netdev_dbg(dev, "form error\n");
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
 		break;
 	case LEC_ACK_ERROR:
 		netdev_dbg(dev, "ack error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
 		break;
 	case LEC_BIT1_ERROR:
 		netdev_dbg(dev, "bit1 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
 		break;
 	case LEC_BIT0_ERROR:
 		netdev_dbg(dev, "bit0 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
 		break;
 	case LEC_CRC_ERROR:
 		netdev_dbg(dev, "CRC error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
 		break;
 	default:
 		break;
 	}
 
+	if (unlikely(!skb))
+		return 0;
+
 	if (cdev->is_peripheral)
 		timestamp = m_can_get_timestamp(cdev);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 07/12] can: ifi_canfd: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (5 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 06/12] can: m_can: fix {rx,tx}_errors statistics Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-23 20:14   ` Marek Vasut
  2024-11-22 22:15 ` [PATCH v2 08/12] can: hi311x: " Dario Binacchi
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Marc Kleine-Budde, Marek Vasut,
	Uwe Kleine-König, Vincent Mailhol, linux-can

The ifi_canfd_handle_lec_err() function was incorrectly incrementing only
the receive error counter, even in cases of bit or acknowledgment errors
that occur during transmission. The patch fixes the issue by incrementing
the appropriate counter based on the type of error.

Fixes: 5bbd655a8bd0 ("can: ifi: Add more detailed error reporting")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++++---------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index d32b10900d2f..c86b57d47085 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -390,36 +390,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
 		return 0;
 
 	priv->can.can_stats.bus_error++;
-	stats->rx_errors++;
 
 	/* Propagate the error condition to the CAN stack. */
 	skb = alloc_can_err_skb(ndev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* Read the error counter register and check for new errors. */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+	}
 
-	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+	}
 
 	/* Reset the error counter, ack the IRQ and re-enable the counter. */
 	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
@@ -427,6 +446,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
 	       priv->base + IFI_CANFD_INTERRUPT);
 	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
 
+	if (unlikely(!skb))
+		return 0;
+
 	netif_receive_skb(skb);
 
 	return 1;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 08/12] can: hi311x: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (6 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 07/12] can: ifi_canfd: " Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 09/12] can: sja1000: " Dario Binacchi
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Akshay Bhat, Krzysztof Kozlowski,
	Marc Kleine-Budde, Vincent Mailhol, Wolfgang Grandegger,
	linux-can

The hi3110_can_ist() function was incorrectly incrementing only the
receive error counter, even in cases of bit or acknowledgment errors that
occur during transmission. The patch fixes the issue by incrementing the
appropriate counter based on the type of error.

Fixes: 57e83fb9b746 ("can: hi311x: Add Holt HI-311x CAN driver")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/spi/hi311x.c | 47 ++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 25d9b32f5701..09ae218315d7 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -696,27 +696,38 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
 			/* Check for protocol errors */
 			if (eflag & HI3110_ERR_PROTOCOL_MASK) {
 				skb = alloc_can_err_skb(net, &cf);
-				if (!skb)
-					break;
+				if (skb)
+					cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-				cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 				priv->can.can_stats.bus_error++;
-				priv->net->stats.rx_errors++;
-				if (eflag & HI3110_ERR_BITERR)
-					cf->data[2] |= CAN_ERR_PROT_BIT;
-				else if (eflag & HI3110_ERR_FRMERR)
-					cf->data[2] |= CAN_ERR_PROT_FORM;
-				else if (eflag & HI3110_ERR_STUFERR)
-					cf->data[2] |= CAN_ERR_PROT_STUFF;
-				else if (eflag & HI3110_ERR_CRCERR)
-					cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
-				else if (eflag & HI3110_ERR_ACKERR)
-					cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
-
-				cf->data[6] = hi3110_read(spi, HI3110_READ_TEC);
-				cf->data[7] = hi3110_read(spi, HI3110_READ_REC);
+				if (eflag & HI3110_ERR_BITERR) {
+					priv->net->stats.tx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_BIT;
+				} else if (eflag & HI3110_ERR_FRMERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_FORM;
+				} else if (eflag & HI3110_ERR_STUFERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_STUFF;
+				} else if (eflag & HI3110_ERR_CRCERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+				} else if (eflag & HI3110_ERR_ACKERR) {
+					priv->net->stats.tx_errors++;
+					if (skb)
+						cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+				}
+
 				netdev_dbg(priv->net, "Bus Error\n");
-				netif_rx(skb);
+				if (skb) {
+					cf->data[6] = hi3110_read(spi, HI3110_READ_TEC);
+					cf->data[7] = hi3110_read(spi, HI3110_READ_REC);
+					netif_rx(skb);
+				}
 			}
 		}
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 09/12] can: sja1000: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (7 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 08/12] can: hi311x: " Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 10/12] can: sun4i_can: " Dario Binacchi
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, David S. Miller, Marc Kleine-Budde,
	Oliver Hartkopp, Vincent Mailhol, Wolfgang Grandegger, linux-can

The sja1000_err() function only incremented the receive error counter
and never the transmit error counter, even if the ECC_DIR flag reported
that an error had occurred during transmission. Increment the
receive/transmit error counter based on the value of the ECC_DIR flag.

Fixes: 429da1cc841b ("can: Driver for the SJA1000 CAN controller")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/sja1000/sja1000.c | 67 ++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index ddb3247948ad..4d245857ef1c 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -416,8 +416,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 	int ret = 0;
 
 	skb = alloc_can_err_skb(dev, &cf);
-	if (skb == NULL)
-		return -ENOMEM;
 
 	txerr = priv->read_reg(priv, SJA1000_TXERR);
 	rxerr = priv->read_reg(priv, SJA1000_RXERR);
@@ -425,8 +423,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 	if (isrc & IRQ_DOI) {
 		/* data overrun interrupt */
 		netdev_dbg(dev, "data overrun interrupt\n");
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		}
+
 		stats->rx_over_errors++;
 		stats->rx_errors++;
 		sja1000_write_cmdreg(priv, CMD_CDO);	/* clear bit */
@@ -452,7 +453,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 		else
 			state = CAN_STATE_ERROR_ACTIVE;
 	}
-	if (state != CAN_STATE_BUS_OFF) {
+	if (state != CAN_STATE_BUS_OFF && skb) {
 		cf->can_id |= CAN_ERR_CNT;
 		cf->data[6] = txerr;
 		cf->data[7] = rxerr;
@@ -460,33 +461,38 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 	if (isrc & IRQ_BEI) {
 		/* bus error interrupt */
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
 		ecc = priv->read_reg(priv, SJA1000_ECC);
+		if (skb) {
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-
-		/* set error type */
-		switch (ecc & ECC_MASK) {
-		case ECC_BIT:
-			cf->data[2] |= CAN_ERR_PROT_BIT;
-			break;
-		case ECC_FORM:
-			cf->data[2] |= CAN_ERR_PROT_FORM;
-			break;
-		case ECC_STUFF:
-			cf->data[2] |= CAN_ERR_PROT_STUFF;
-			break;
-		default:
-			break;
-		}
+			/* set error type */
+			switch (ecc & ECC_MASK) {
+			case ECC_BIT:
+				cf->data[2] |= CAN_ERR_PROT_BIT;
+				break;
+			case ECC_FORM:
+				cf->data[2] |= CAN_ERR_PROT_FORM;
+				break;
+			case ECC_STUFF:
+				cf->data[2] |= CAN_ERR_PROT_STUFF;
+				break;
+			default:
+				break;
+			}
 
-		/* set error location */
-		cf->data[3] = ecc & ECC_SEG;
+			/* set error location */
+			cf->data[3] = ecc & ECC_SEG;
+		}
 
 		/* Error occurred during transmission? */
-		if ((ecc & ECC_DIR) == 0)
-			cf->data[2] |= CAN_ERR_PROT_TX;
+		if ((ecc & ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
+		}
 	}
 	if (isrc & IRQ_EPI) {
 		/* error passive interrupt */
@@ -502,8 +508,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 		netdev_dbg(dev, "arbitration lost interrupt\n");
 		alc = priv->read_reg(priv, SJA1000_ALC);
 		priv->can.can_stats.arbitration_lost++;
-		cf->can_id |= CAN_ERR_LOSTARB;
-		cf->data[0] = alc & 0x1f;
+		if (skb) {
+			cf->can_id |= CAN_ERR_LOSTARB;
+			cf->data[0] = alc & 0x1f;
+		}
 	}
 
 	if (state != priv->can.state) {
@@ -516,6 +524,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 			can_bus_off(dev);
 	}
 
+	if (!skb)
+		return -ENOMEM;
+
 	netif_rx(skb);
 
 	return ret;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 10/12] can: sun4i_can: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (8 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 09/12] can: sja1000: " Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-26  9:32   ` Marc Kleine-Budde
  2024-11-22 22:15 ` [PATCH v2 11/12] can: ems_usb: " Dario Binacchi
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Chen-Yu Tsai, Gerhard Bertelsmann,
	Jernej Skrabec, Marc Kleine-Budde, Maxime Ripard, Samuel Holland,
	Vincent Mailhol, linux-arm-kernel, linux-can, linux-sunxi

The sun4i_can_err() function only incremented the receive error counter
and never the transmit error counter, even if the STA_ERR_DIR flag
reported that an error had occurred during transmission. Increment the
receive/transmit error counter based on the value of the STA_ERR_DIR
flag.

Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/sun4i_can.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 840b972498c1..5285bb0b7c69 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -579,7 +579,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
 		/* bus error interrupt */
 		netdev_dbg(dev, "bus error interrupt\n");
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
 		if (likely(skb)) {
 			ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
@@ -601,9 +600,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
 					       >> 16;
 				break;
 			}
-			/* error occurred during transmission? */
-			if ((ecc & SUN4I_STA_ERR_DIR) == 0)
+		}
+
+		/* error occurred during transmission? */
+		if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
+			if (likely(skb))
 				cf->data[2] |= CAN_ERR_PROT_TX;
+			stats->tx_errors++;
+		} else {
+			stats->rx_errors++;
 		}
 	}
 	if (isrc & SUN4I_INT_ERR_PASSIVE) {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 11/12] can: ems_usb: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (9 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 10/12] can: sun4i_can: " Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-22 22:15 ` [PATCH v2 12/12] can: f81604: " Dario Binacchi
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, David S. Miller, Marc Kleine-Budde,
	Sebastian Haas, Vincent Mailhol, Wolfgang Grandegger, linux-can

The ems_usb_rx_err() function only incremented the receive error counter
and never the transmit error counter, even if the ECC_DIR flag reported
that an error had occurred during transmission. Increment the
receive/transmit error counter based on the value of the ECC_DIR flag.

Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Update statistics even if skb allocation fails

 drivers/net/can/usb/ems_usb.c | 58 ++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 050c0b49938a..5355bac4dccb 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -335,15 +335,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
 	struct net_device_stats *stats = &dev->netdev->stats;
 
 	skb = alloc_can_err_skb(dev->netdev, &cf);
-	if (skb == NULL)
-		return;
 
 	if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
 		u8 state = msg->msg.can_state;
 
 		if (state & SJA1000_SR_BS) {
 			dev->can.state = CAN_STATE_BUS_OFF;
-			cf->can_id |= CAN_ERR_BUSOFF;
+			if (skb)
+				cf->can_id |= CAN_ERR_BUSOFF;
 
 			dev->can.can_stats.bus_off++;
 			can_bus_off(dev->netdev);
@@ -361,44 +360,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
 
 		/* bus error interrupt */
 		dev->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		if (skb) {
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-		switch (ecc & SJA1000_ECC_MASK) {
-		case SJA1000_ECC_BIT:
-			cf->data[2] |= CAN_ERR_PROT_BIT;
-			break;
-		case SJA1000_ECC_FORM:
-			cf->data[2] |= CAN_ERR_PROT_FORM;
-			break;
-		case SJA1000_ECC_STUFF:
-			cf->data[2] |= CAN_ERR_PROT_STUFF;
-			break;
-		default:
-			cf->data[3] = ecc & SJA1000_ECC_SEG;
-			break;
+			switch (ecc & SJA1000_ECC_MASK) {
+			case SJA1000_ECC_BIT:
+				cf->data[2] |= CAN_ERR_PROT_BIT;
+				break;
+			case SJA1000_ECC_FORM:
+				cf->data[2] |= CAN_ERR_PROT_FORM;
+				break;
+			case SJA1000_ECC_STUFF:
+				cf->data[2] |= CAN_ERR_PROT_STUFF;
+				break;
+			default:
+				cf->data[3] = ecc & SJA1000_ECC_SEG;
+				break;
+			}
 		}
 
 		/* Error occurred during transmission? */
-		if ((ecc & SJA1000_ECC_DIR) == 0)
-			cf->data[2] |= CAN_ERR_PROT_TX;
+		if ((ecc & SJA1000_ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
+		}
 
-		if (dev->can.state == CAN_STATE_ERROR_WARNING ||
-		    dev->can.state == CAN_STATE_ERROR_PASSIVE) {
+		if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING ||
+			    dev->can.state == CAN_STATE_ERROR_PASSIVE)) {
 			cf->can_id |= CAN_ERR_CRTL;
 			cf->data[1] = (txerr > rxerr) ?
 			    CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
 		}
 	} else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		}
 
 		stats->rx_over_errors++;
 		stats->rx_errors++;
 	}
 
-	netif_rx(skb);
+	if (skb)
+		netif_rx(skb);
 }
 
 /*
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 12/12] can: f81604: fix {rx,tx}_errors statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (10 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 11/12] can: ems_usb: " Dario Binacchi
@ 2024-11-22 22:15 ` Dario Binacchi
  2024-11-26  9:42 ` [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Marc Kleine-Budde
  2024-11-26 10:14 ` Marc Kleine-Budde
  13 siblings, 0 replies; 19+ messages in thread
From: Dario Binacchi @ 2024-11-22 22:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Ji-Ze Hong (Peter Hong),
	Marc Kleine-Budde, Vincent Mailhol, linux-can

The f81604_handle_can_bus_errors() function only incremented the receive
error counter and never the transmit error counter, even if the ECC_DIR
flag reported that an error had occurred during transmission. Increment
the receive/transmit error counter based on the value of the ECC_DIR
flag.

Fixes: 88da17436973 ("can: usb: f81604: add Fintek F81604 support")
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

Changes in v2:
- Fix patches 7 through 12 to ensure that statistics are updated even
  if the allocation of skb fails.
- Add five new patches (i. e. 1-5), created during the further analysis
  of the code while correcting patches from the v1 series (i. e. 7-12).
- Update statistics even if skb allocation fails

 drivers/net/can/usb/f81604.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/usb/f81604.c b/drivers/net/can/usb/f81604.c
index bc0c8903fe77..e0cfa1460b0b 100644
--- a/drivers/net/can/usb/f81604.c
+++ b/drivers/net/can/usb/f81604.c
@@ -526,7 +526,6 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv,
 		netdev_dbg(netdev, "bus error interrupt\n");
 
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
 		if (skb) {
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
@@ -548,10 +547,15 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv,
 
 			/* set error location */
 			cf->data[3] = data->ecc & F81604_SJA1000_ECC_SEG;
+		}
 
-			/* Error occurred during transmission? */
-			if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0)
+		/* Error occurred during transmission? */
+		if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
 				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
 		}
 
 		set_bit(F81604_CLEAR_ECC, &priv->clear_flags);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 07/12] can: ifi_canfd: fix {rx,tx}_errors statistics
  2024-11-22 22:15 ` [PATCH v2 07/12] can: ifi_canfd: " Dario Binacchi
@ 2024-11-23 20:14   ` Marek Vasut
  0 siblings, 0 replies; 19+ messages in thread
From: Marek Vasut @ 2024-11-23 20:14 UTC (permalink / raw)
  To: Dario Binacchi, linux-kernel
  Cc: linux-amarula, Marc Kleine-Budde, Uwe Kleine-König,
	Vincent Mailhol, linux-can

On 11/22/24 11:15 PM, Dario Binacchi wrote:
> The ifi_canfd_handle_lec_err() function was incorrectly incrementing only
> the receive error counter, even in cases of bit or acknowledgment errors
> that occur during transmission. The patch fixes the issue by incrementing
> the appropriate counter based on the type of error.
> 
> Fixes: 5bbd655a8bd0 ("can: ifi: Add more detailed error reporting")
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
The multitude of if (likely(skb)) in the patch is super-ugly, but I do 
agree the change itself seems valid to me, so:

Reviewed-by: Marek Vasut <marex@denx.de>

Thanks !

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb
  2024-11-22 22:15 ` [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb Dario Binacchi
@ 2024-11-26  9:18   ` Marc Kleine-Budde
  0 siblings, 0 replies; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-11-26  9:18 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Chen-Yu Tsai, Jernej Skrabec,
	Samuel Holland, Vincent Mailhol, linux-arm-kernel, linux-can,
	linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 638 bytes --]

On 22.11.2024 23:15:44, Dario Binacchi wrote:
> Throughout the sun4i_can_err() function, the likely() macro is used to
> check the skb buffer, except in one instance. This patch makes the code
> consistent by using the macro in that case as well.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

I'll apply this one on can-next.

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   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 10/12] can: sun4i_can: fix {rx,tx}_errors statistics
  2024-11-22 22:15 ` [PATCH v2 10/12] can: sun4i_can: " Dario Binacchi
@ 2024-11-26  9:32   ` Marc Kleine-Budde
  0 siblings, 0 replies; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-11-26  9:32 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Chen-Yu Tsai, Gerhard Bertelsmann,
	Jernej Skrabec, Maxime Ripard, Samuel Holland, Vincent Mailhol,
	linux-arm-kernel, linux-can, linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 3330 bytes --]

On 22.11.2024 23:15:51, Dario Binacchi wrote:
> The sun4i_can_err() function only incremented the receive error counter
> and never the transmit error counter, even if the STA_ERR_DIR flag
> reported that an error had occurred during transmission. Increment the
> receive/transmit error counter based on the value of the STA_ERR_DIR
> flag.
> 
> Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

Fails to build from source:

| drivers/net/can/sun4i_can.c:583:7: error: variable 'ecc' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
|   583 |                 if (likely(skb)) {
|       |                     ^~~~~~~~~~~
| include/linux/compiler.h:76:20: note: expanded from macro 'likely'
|    76 | # define likely(x)      __builtin_expect(!!(x), 1)
|       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
| drivers/net/can/sun4i_can.c:606:8: note: uninitialized use occurs here
|   606 |                 if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
|       |                      ^~~
| drivers/net/can/sun4i_can.c:583:3: note: remove the 'if' if its condition is always true
|   583 |                 if (likely(skb)) {
|       |                 ^~~~~~~~~~~~~~~~
| drivers/net/can/sun4i_can.c:534:9: note: initialize the variable 'ecc' to silence this warning
|   534 |         u32 ecc, alc;
|       |                ^
|       |                 = 0
| 1 error generated.

Fixes by moving the "ecc = readl();":

--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -579,11 +579,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
                 /* bus error interrupt */
                 netdev_dbg(dev, "bus error interrupt\n");
                 priv->can.can_stats.bus_error++;
-                stats->rx_errors++;
+                ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
 
                 if (likely(skb)) {
-                        ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
-
                         cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
                         switch (ecc & SUN4I_STA_MASK_ERR) {
@@ -601,9 +599,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
                                                >> 16;
                                 break;
                         }
-                        /* error occurred during transmission? */
-                        if ((ecc & SUN4I_STA_ERR_DIR) == 0)
+                }
+
+                /* error occurred during transmission? */
+                if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
+                        if (likely(skb))
                                 cf->data[2] |= CAN_ERR_PROT_TX;
+                        stats->tx_errors++;
+                } else {
+                        stats->rx_errors++;
                 }
         }
         if (isrc & SUN4I_INT_ERR_PASSIVE) {


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   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (11 preceding siblings ...)
  2024-11-22 22:15 ` [PATCH v2 12/12] can: f81604: " Dario Binacchi
@ 2024-11-26  9:42 ` Marc Kleine-Budde
  2024-11-26 10:14 ` Marc Kleine-Budde
  13 siblings, 0 replies; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-11-26  9:42 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Akshay Bhat,
	Chandrasekar Ramakrishnan, Chen-Yu Tsai, David S. Miller,
	Dong Aisheng, Fengguang Wu, Gerhard Bertelsmann, Jernej Skrabec,
	Ji-Ze Hong (Peter Hong), Krzysztof Kozlowski, Marek Vasut,
	Maxime Ripard, Oliver Hartkopp, Samuel Holland, Sebastian Haas,
	Uwe Kleine-König, Varka Bhadram, Vincent Mailhol,
	Wolfgang Grandegger, linux-arm-kernel, linux-can, linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 653 bytes --]

On 22.11.2024 23:15:41, Dario Binacchi wrote:
> This series extends the patch 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics"),
> already merged into the mainline, to other CAN devices that similarly do
> not correctly increment the error counters for reception/transmission.

I've re-phrased the commit messages of the earlier patches to imperative
language.

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   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting
  2024-11-22 22:15 ` [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting Dario Binacchi
@ 2024-11-26  9:48   ` Marc Kleine-Budde
  0 siblings, 0 replies; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-11-26  9:48 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Krzysztof Kozlowski, Vincent Mailhol,
	linux-can

[-- Attachment #1: Type: text/plain, Size: 1417 bytes --]

On 22.11.2024 23:15:45, Dario Binacchi wrote:
> The commit a22bd630cfff ("can: hi311x: do not report txerr and rxerr
> during bus-off") removed the reporting of rxerr and txerr even in case
> of correct operation (i. e. not bus-off). The CAN frame is unnecessarily
> set since netif_rx() has already been called. The patch fixes the issue
> by postponing the netif_rx() call in case of txerr and rxerr reporting.

re-phrased to:

can: hi311x: hi3110_can_ist(): fix potential use-after-free

The commit a22bd630cfff ("can: hi311x: do not report txerr and rxerr
during bus-off") removed the reporting of rxerr and txerr even in case
of correct operation (i. e. not bus-off).

The error count information added to the CAN frame after netif_rx() is
a potential use after free, since there is no guarantee that the skb
is in the same state. It might be freed or reused.

Fix the issue by postponing the netif_rx() call in case of txerr and
rxerr reporting.

> Fixes: a22bd630cfff ("can: hi311x: do not report txerr and rxerr during bus-off")
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

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   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics
  2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
                   ` (12 preceding siblings ...)
  2024-11-26  9:42 ` [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Marc Kleine-Budde
@ 2024-11-26 10:14 ` Marc Kleine-Budde
  13 siblings, 0 replies; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-11-26 10:14 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Akshay Bhat,
	Chandrasekar Ramakrishnan, Chen-Yu Tsai, David S. Miller,
	Dong Aisheng, Fengguang Wu, Gerhard Bertelsmann, Jernej Skrabec,
	Ji-Ze Hong (Peter Hong), Krzysztof Kozlowski, Marek Vasut,
	Maxime Ripard, Oliver Hartkopp, Samuel Holland, Sebastian Haas,
	Uwe Kleine-König, Varka Bhadram, Vincent Mailhol,
	Wolfgang Grandegger, linux-arm-kernel, linux-can, linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 941 bytes --]

On 22.11.2024 23:15:41, Dario Binacchi wrote:
> This series extends the patch 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics"),
> already merged into the mainline, to other CAN devices that similarly do
> not correctly increment the error counters for reception/transmission.
> 
> Changes in v2:
> - Fix patches 7 through 12 to ensure that statistics are updated even
>   if the allocation of skb fails.
> - Add five new patches (i. e. 1-5), created during the further analysis
>   of the code while correcting patches from the v1 series (i. e. 7-12).

Applied with some changes to linux-can, omitted patch 3, it will to into
linux-can-next.

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   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-11-26 10:14 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-22 22:15 [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 01/12] can: c_can: update statistics if skb allocation fails Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 02/12] can: sun4i_can: call can_change_state() even if cf is NULL Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 03/12] can: sun4i_can: continue to use likely() to check skb Dario Binacchi
2024-11-26  9:18   ` Marc Kleine-Budde
2024-11-22 22:15 ` [PATCH v2 04/12] can: hi311x: fix txerr and rxerr reporting Dario Binacchi
2024-11-26  9:48   ` Marc Kleine-Budde
2024-11-22 22:15 ` [PATCH v2 05/12] can: hi311x: update state error statistics if skb allocation fails Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 06/12] can: m_can: fix {rx,tx}_errors statistics Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 07/12] can: ifi_canfd: " Dario Binacchi
2024-11-23 20:14   ` Marek Vasut
2024-11-22 22:15 ` [PATCH v2 08/12] can: hi311x: " Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 09/12] can: sja1000: " Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 10/12] can: sun4i_can: " Dario Binacchi
2024-11-26  9:32   ` Marc Kleine-Budde
2024-11-22 22:15 ` [PATCH v2 11/12] can: ems_usb: " Dario Binacchi
2024-11-22 22:15 ` [PATCH v2 12/12] can: f81604: " Dario Binacchi
2024-11-26  9:42 ` [PATCH v2 00/12] Fix {rx,tx}_errors CAN statistics Marc Kleine-Budde
2024-11-26 10:14 ` Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox