linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes
@ 2021-07-15 14:28 Stephane Grosjean
  2021-07-15 14:28 ` [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB Stephane Grosjean
  2021-07-16  9:57 ` [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes Marc Kleine-Budde
  0 siblings, 2 replies; 5+ messages in thread
From: Stephane Grosjean @ 2021-07-15 14:28 UTC (permalink / raw)
  To: linux-can Mailing List; +Cc: Stephane Grosjean

This patch updates old code by using the functions published since by the
socket-can module. In particular, this new code better manages the change
of bus state by also using the value of the error counters that the driver
now systematically asks for when initializing the channel.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
---
v2:
 - do the statistics and state update, even if the allocation of the skb
   fails.
v3:
 - do call can_change_state() even when cf is NULL
 - do supply Tx/Rx error counters in controller error skb
---
 drivers/net/can/usb/peak_usb/pcan_usb.c | 161 ++++++------------------
 1 file changed, 40 insertions(+), 121 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 1d6f77252f01..3af3136645ac 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -445,145 +445,64 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
 {
 	struct sk_buff *skb;
 	struct can_frame *cf;
-	enum can_state new_state;
+	enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
 
 	/* ignore this error until 1st ts received */
 	if (n == PCAN_USB_ERROR_QOVR)
 		if (!mc->pdev->time_ref.tick_count)
 			return 0;
 
-	new_state = mc->pdev->dev.can.state;
-
-	switch (mc->pdev->dev.can.state) {
-	case CAN_STATE_ERROR_ACTIVE:
-		if (n & PCAN_USB_ERROR_BUS_LIGHT) {
-			new_state = CAN_STATE_ERROR_WARNING;
-			break;
-		}
-		fallthrough;
-
-	case CAN_STATE_ERROR_WARNING:
-		if (n & PCAN_USB_ERROR_BUS_HEAVY) {
-			new_state = CAN_STATE_ERROR_PASSIVE;
-			break;
-		}
-		if (n & PCAN_USB_ERROR_BUS_OFF) {
-			new_state = CAN_STATE_BUS_OFF;
-			break;
-		}
-		if (n & ~PCAN_USB_ERROR_BUS) {
-			/*
-			 * trick to bypass next comparison and process other
-			 * errors
-			 */
-			new_state = CAN_STATE_MAX;
-			break;
-		}
-		if ((n & PCAN_USB_ERROR_BUS_LIGHT) == 0) {
-			/* no error (back to active state) */
-			new_state = CAN_STATE_ERROR_ACTIVE;
-			break;
-		}
-		break;
-
-	case CAN_STATE_ERROR_PASSIVE:
-		if (n & PCAN_USB_ERROR_BUS_OFF) {
-			new_state = CAN_STATE_BUS_OFF;
-			break;
-		}
-		if (n & PCAN_USB_ERROR_BUS_LIGHT) {
-			new_state = CAN_STATE_ERROR_WARNING;
-			break;
-		}
-		if (n & ~PCAN_USB_ERROR_BUS) {
-			/*
-			 * trick to bypass next comparison and process other
-			 * errors
-			 */
-			new_state = CAN_STATE_MAX;
-			break;
-		}
-
-		if ((n & PCAN_USB_ERROR_BUS_HEAVY) == 0) {
-			/* no error (back to warning state) */
-			new_state = CAN_STATE_ERROR_WARNING;
-			break;
-		}
-		break;
-
-	default:
-		/* do nothing waiting for restart */
-		return 0;
-	}
-
-	/* donot post any error if current state didn't change */
-	if (mc->pdev->dev.can.state == new_state)
-		return 0;
-
 	/* allocate an skb to store the error frame */
 	skb = alloc_can_err_skb(mc->netdev, &cf);
-	if (!skb)
-		return -ENOMEM;
 
-	switch (new_state) {
-	case CAN_STATE_BUS_OFF:
-		cf->can_id |= CAN_ERR_BUSOFF;
-		mc->pdev->dev.can.can_stats.bus_off++;
-		can_bus_off(mc->netdev);
-		break;
-
-	case CAN_STATE_ERROR_PASSIVE:
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = (mc->pdev->bec.txerr > mc->pdev->bec.rxerr) ?
-				CAN_ERR_CRTL_TX_PASSIVE :
-				CAN_ERR_CRTL_RX_PASSIVE;
-		cf->data[6] = mc->pdev->bec.txerr;
-		cf->data[7] = mc->pdev->bec.rxerr;
-
-		mc->pdev->dev.can.can_stats.error_passive++;
-		break;
+	if (n & PCAN_USB_ERROR_RXQOVR) {
+		/* data overrun interrupt */
+		netdev_dbg(mc->netdev, "data overrun interrupt\n");
+		mc->netdev->stats.rx_over_errors++;
+		mc->netdev->stats.rx_errors++;
+		if (cf) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+		}
+	}
 
-	case CAN_STATE_ERROR_WARNING:
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = (mc->pdev->bec.txerr > mc->pdev->bec.rxerr) ?
-				CAN_ERR_CRTL_TX_WARNING :
-				CAN_ERR_CRTL_RX_WARNING;
-		cf->data[6] = mc->pdev->bec.txerr;
-		cf->data[7] = mc->pdev->bec.rxerr;
+	if (n & PCAN_USB_ERROR_TXQFULL)
+		netdev_dbg(mc->netdev, "device Tx queue full)\n");
 
-		mc->pdev->dev.can.can_stats.error_warning++;
-		break;
+	if (n & PCAN_USB_ERROR_BUS_OFF) {
+		new_state = CAN_STATE_BUS_OFF;
+	} else if (n & PCAN_USB_ERROR_BUS_HEAVY) {
+		new_state = ((mc->pdev->bec.txerr >= 128) ||
+			     (mc->pdev->bec.rxerr >= 128)) ?
+				CAN_STATE_ERROR_PASSIVE :
+				CAN_STATE_ERROR_WARNING;
+	} else {
+		new_state = CAN_STATE_ERROR_ACTIVE;
+	}
 
-	case CAN_STATE_ERROR_ACTIVE:
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = CAN_ERR_CRTL_ACTIVE;
+	/* handle change of state */
+	if (new_state != mc->pdev->dev.can.state) {
+		enum can_state tx_state =
+			(mc->pdev->bec.txerr >= mc->pdev->bec.rxerr) ?
+				new_state : 0;
+		enum can_state rx_state =
+			(mc->pdev->bec.txerr <= mc->pdev->bec.rxerr) ?
+				new_state : 0;
 
-		/* sync local copies of rxerr/txerr counters */
-		mc->pdev->bec.txerr = 0;
-		mc->pdev->bec.rxerr = 0;
-		break;
+		can_change_state(mc->netdev, cf, tx_state, rx_state);
 
-	default:
-		/* CAN_STATE_MAX (trick to handle other errors) */
-		if (n & PCAN_USB_ERROR_TXQFULL)
-			netdev_dbg(mc->netdev, "device Tx queue full)\n");
+		if (new_state == CAN_STATE_BUS_OFF) {
+			can_bus_off(mc->netdev);
 
-		if (n & PCAN_USB_ERROR_RXQOVR) {
-			netdev_dbg(mc->netdev, "data overrun interrupt\n");
-			cf->can_id |= CAN_ERR_CRTL;
-			cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
-			mc->netdev->stats.rx_over_errors++;
-			mc->netdev->stats.rx_errors++;
+		/* supply tx/rx error counters in case of controller error */
+		} else if (cf && (cf->can_id & CAN_ERR_CRTL)) {
+			cf->data[6] = mc->pdev->bec.txerr;
+			cf->data[7] = mc->pdev->bec.rxerr;
 		}
-
-		cf->data[6] = mc->pdev->bec.txerr;
-		cf->data[7] = mc->pdev->bec.rxerr;
-
-		new_state = mc->pdev->dev.can.state;
-		break;
 	}
 
-	mc->pdev->dev.can.state = new_state;
+	if (!skb)
+		return -ENOMEM;
 
 	if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
 		struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
-- 
2.25.1


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

* [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB
  2021-07-15 14:28 [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes Stephane Grosjean
@ 2021-07-15 14:28 ` Stephane Grosjean
  2021-07-16  9:19   ` Marc Kleine-Budde
  2021-07-16  9:56   ` Marc Kleine-Budde
  2021-07-16  9:57 ` [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes Marc Kleine-Budde
  1 sibling, 2 replies; 5+ messages in thread
From: Stephane Grosjean @ 2021-07-15 14:28 UTC (permalink / raw)
  To: linux-can Mailing List; +Cc: Stephane Grosjean

When the driver detects that the PCAN-USB device runs an old firmware
(< 4.1) then it prints a message suggesting to contact
<support@peak-system.com> for a possible firmware update.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 3af3136645ac..cb492584fdb0 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -850,6 +850,19 @@ static int pcan_usb_init(struct peak_usb_device *dev)
 		 pcan_usb.name, dev->device_rev, serial_number,
 		 pcan_usb.ctrl_count);
 
+	/* Since rev 4.1, PCAN-USB is able to make single-short as well as
+	 * looped back frames.
+	 */
+	if (dev->device_rev >= 41) {
+		struct can_priv *priv = netdev_priv(dev->netdev);
+
+		priv->ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT |
+					    CAN_CTRLMODE_LOOPBACK;
+	} else {
+		dev_info(dev->netdev->dev.parent,
+			 "Firmware update available. Please contact support@peak-system.com\n");
+	}
+
 	return 0;
 }
 
-- 
2.25.1


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

* Re: [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB
  2021-07-15 14:28 ` [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB Stephane Grosjean
@ 2021-07-16  9:19   ` Marc Kleine-Budde
  2021-07-16  9:56   ` Marc Kleine-Budde
  1 sibling, 0 replies; 5+ messages in thread
From: Marc Kleine-Budde @ 2021-07-16  9:19 UTC (permalink / raw)
  To: Stephane Grosjean; +Cc: linux-can Mailing List

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

On 15.07.2021 16:28:42, Stephane Grosjean wrote:
> When the driver detects that the PCAN-USB device runs an old firmware
> (< 4.1) then it prints a message suggesting to contact
> <support@peak-system.com> for a possible firmware update.
> 
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
> ---
>  drivers/net/can/usb/peak_usb/pcan_usb.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
> index 3af3136645ac..cb492584fdb0 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
> @@ -850,6 +850,19 @@ static int pcan_usb_init(struct peak_usb_device *dev)
>  		 pcan_usb.name, dev->device_rev, serial_number,
>  		 pcan_usb.ctrl_count);
>  
> +	/* Since rev 4.1, PCAN-USB is able to make single-short as well as
                                                             ^

Fixed typo while applying.

> +	 * looped back frames.
> +	 */
> +	if (dev->device_rev >= 41) {
> +		struct can_priv *priv = netdev_priv(dev->netdev);
> +
> +		priv->ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT |
> +					    CAN_CTRLMODE_LOOPBACK;
> +	} else {
> +		dev_info(dev->netdev->dev.parent,
> +			 "Firmware update available. Please contact support@peak-system.com\n");
> +	}
> +
>  	return 0;
>  }

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

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

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

* Re: [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB
  2021-07-15 14:28 ` [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB Stephane Grosjean
  2021-07-16  9:19   ` Marc Kleine-Budde
@ 2021-07-16  9:56   ` Marc Kleine-Budde
  1 sibling, 0 replies; 5+ messages in thread
From: Marc Kleine-Budde @ 2021-07-16  9:56 UTC (permalink / raw)
  To: Stephane Grosjean; +Cc: linux-can Mailing List

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

On 15.07.2021 16:28:42, Stephane Grosjean wrote:
> When the driver detects that the PCAN-USB device runs an old firmware
> (< 4.1) then it prints a message suggesting to contact
> <support@peak-system.com> for a possible firmware update.
> 
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>

Squashed into the "can: peak_usb: PCAN-USB: add support of loopback and
one-shot mode" patch

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

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

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

* Re: [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes
  2021-07-15 14:28 [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes Stephane Grosjean
  2021-07-15 14:28 ` [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB Stephane Grosjean
@ 2021-07-16  9:57 ` Marc Kleine-Budde
  1 sibling, 0 replies; 5+ messages in thread
From: Marc Kleine-Budde @ 2021-07-16  9:57 UTC (permalink / raw)
  To: Stephane Grosjean; +Cc: linux-can Mailing List

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

On 15.07.2021 16:28:41, Stephane Grosjean wrote:
> This patch updates old code by using the functions published since by the
> socket-can module. In particular, this new code better manages the change
> of bus state by also using the value of the error counters that the driver
> now systematically asks for when initializing the channel.
> 
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>

Added to linux-can-next/testing

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

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

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

end of thread, other threads:[~2021-07-16  9:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-15 14:28 [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes Stephane Grosjean
2021-07-15 14:28 ` [PATCH v3 2/2] can: peak_usb: Add a "firmware update available" msg to old PCAN-USB Stephane Grosjean
2021-07-16  9:19   ` Marc Kleine-Budde
2021-07-16  9:56   ` Marc Kleine-Budde
2021-07-16  9:57 ` [PATCH v3 1/2] can: peak_usb: upgrades the handling of bus state changes 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;
as well as URLs for NNTP newsgroup(s).