Commit bb03d568 authored by Dario Binacchi's avatar Dario Binacchi Committed by Marc Kleine-Budde
Browse files

can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics



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.

Fix the issue by incrementing the appropriate counter based on the
type of error.

Fixes: 5bbd655a ("can: ifi: Add more detailed error reporting")
Signed-off-by: default avatarDario Binacchi <dario.binacchi@amarulasolutions.com>
Reviewed-by: default avatarMarek Vasut <marex@denx.de>
Link: https://patch.msgid.link/20241122221650.633981-8-dario.binacchi@amarulasolutions.com


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 988d4222
Loading
Loading
Loading
Loading
+40 −18
Original line number Diff line number Diff line
@@ -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. */
	if (likely(skb))
		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;

	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
	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)
	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)
	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)
	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)
	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)
	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)
	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;