From deb8534e8ef3905b5a977486d11d4d36b4f94347 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 29 Sep 2022 09:58:30 +0200 Subject: [PATCH 1/7] can: gs_usb: gs_can_open(): allow loopback and listen only at the same time There's no reason why loopback and listen only should not be allowed at the same time. Replace the "else if" by "if" to reflect this in the code. Link: https://lore.kernel.org/all/20221019221016.1659260-2-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 384847b4a4c95..aa6c84b7db066 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -911,7 +911,8 @@ static int gs_can_open(struct net_device *netdev) /* flags */ if (ctrlmode & CAN_CTRLMODE_LOOPBACK) flags |= GS_CAN_MODE_LOOP_BACK; - else if (ctrlmode & CAN_CTRLMODE_LISTENONLY) + + if (ctrlmode & CAN_CTRLMODE_LISTENONLY) flags |= GS_CAN_MODE_LISTEN_ONLY; /* Controller is not allowed to retry TX From f6adf410f70b6875ba6412e8909c742c3853201d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 29 Sep 2022 10:01:22 +0200 Subject: [PATCH 2/7] can: gs_usb: gs_can_open(): sort checks for ctrlmode Sort the checks for dev->can.ctrlmode by values of CAN_CTRLMODE_*, so that it's clear where to add new checks. While there, remove the comment that the Atmel UC3C hardware doesn't support One Shot Mode. The One Shot mode is only available and to be activated by the user, if the device specifies the feature bit GS_CAN_FEATURE_ONE_SHOT. Link: https://lore.kernel.org/all/20221019221016.1659260-3-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index aa6c84b7db066..5dad0ebb3d3e0 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -843,8 +843,6 @@ static int gs_can_open(struct net_device *netdev) ctrlmode = dev->can.ctrlmode; if (ctrlmode & CAN_CTRLMODE_FD) { - flags |= GS_CAN_MODE_FD; - if (dev->feature & GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX) dev->hf_size_tx = struct_size(hf, canfd_quirk, 1); else @@ -915,14 +913,14 @@ static int gs_can_open(struct net_device *netdev) if (ctrlmode & CAN_CTRLMODE_LISTENONLY) flags |= GS_CAN_MODE_LISTEN_ONLY; - /* Controller is not allowed to retry TX - * this mode is unavailable on atmels uc3c hardware - */ + if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) + flags |= GS_CAN_MODE_TRIPLE_SAMPLE; + if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) flags |= GS_CAN_MODE_ONE_SHOT; - if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) - flags |= GS_CAN_MODE_TRIPLE_SAMPLE; + if (ctrlmode & CAN_CTRLMODE_FD) + flags |= GS_CAN_MODE_FD; /* if hardware supports timestamps, enable it */ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) From ac3f25824e4f9be1b36cc8f20572fa32b3079f94 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 29 Sep 2022 10:02:06 +0200 Subject: [PATCH 3/7] can: gs_usb: gs_can_open(): merge setting of timestamp flags and init Merge the bodies of 2 consecutive "if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)" statements. Link: https://lore.kernel.org/all/20221019221016.1659260-4-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 5dad0ebb3d3e0..f9e2b394c71e4 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -923,12 +923,12 @@ static int gs_can_open(struct net_device *netdev) flags |= GS_CAN_MODE_FD; /* if hardware supports timestamps, enable it */ - if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) { flags |= GS_CAN_MODE_HW_TIMESTAMP; - /* start polling timestamp */ - if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) + /* start polling timestamp */ gs_usb_timestamp_init(dev); + } /* finally start device */ dev->can.state = CAN_STATE_ERROR_ACTIVE; From 1f1835264d81da03fcd05646542a622678b379d6 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sun, 28 Aug 2022 10:59:10 +0200 Subject: [PATCH 4/7] can: gs_usb: document GS_CAN_FEATURE_BERR_REPORTING Document the new feature ("GS_CAN_FEATURE_BERR_REPORTING") that indicates that the bus error reporting in the CAN controller can switched on and off with the GS_CAN_MODE_BERR_REPORTING mode bit in the GS_USB_BREQ_MODE control message. Signed-off-by: Jeroen Hofstee Link: https://lore.kernel.org/all/20221019221016.1659260-5-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index f9e2b394c71e4..68e474a762c53 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -134,6 +134,7 @@ struct gs_device_config { /* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */ /* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */ /* GS_CAN_FEATURE_TERMINATION BIT(11) */ +#define GS_CAN_MODE_BERR_REPORTING BIT(12) struct gs_device_mode { __le32 mode; @@ -174,7 +175,8 @@ struct gs_device_termination_state { #define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) #define GS_CAN_FEATURE_BT_CONST_EXT BIT(10) #define GS_CAN_FEATURE_TERMINATION BIT(11) -#define GS_CAN_FEATURE_MASK GENMASK(11, 0) +#define GS_CAN_FEATURE_BERR_REPORTING BIT(12) +#define GS_CAN_FEATURE_MASK GENMASK(12, 0) /* internal quirks - keep in GS_CAN_FEATURE space for now */ From 2f3cdad1c616891ab25ce10c1ac146403605b960 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sun, 28 Aug 2022 10:59:10 +0200 Subject: [PATCH 5/7] can: gs_usb: add ability to enable / disable berr reporting The open source firmware candleLight report bus errors unconditionally. This adds support to enable / disable bus error reporting with the standard netlink property. Signed-off-by: Jeroen Hofstee Link: https://lore.kernel.org/all/20221019221016.1659260-6-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 68e474a762c53..e2e23467caf21 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -921,6 +921,9 @@ static int gs_can_open(struct net_device *netdev) if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) flags |= GS_CAN_MODE_ONE_SHOT; + if (ctrlmode & CAN_CTRLMODE_BERR_REPORTING) + flags |= GS_CAN_MODE_BERR_REPORTING; + if (ctrlmode & CAN_CTRLMODE_FD) flags |= GS_CAN_MODE_FD; @@ -1226,6 +1229,9 @@ static struct gs_can *gs_make_candev(unsigned int channel, } } + if (feature & GS_CAN_FEATURE_BERR_REPORTING) + dev->can.ctrlmode_supported |= CAN_CTRLMODE_BERR_REPORTING; + /* The CANtact Pro from LinkLayer Labs is based on the * LPC54616 µC, which is affected by the NXP LPC USB transfer * erratum. However, the current firmware (version 2) doesn't From 40e1997d4551e6053fc2f61959628da474775dc5 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sun, 28 Aug 2022 12:25:02 +0200 Subject: [PATCH 6/7] can: gs_usb: document GS_CAN_FEATURE_GET_STATE Document the new feature ("GS_CAN_FEATURE_GET_STATE") that indicates that the state of the CAN controller can be queried with the new GS_USB_BREQ_GET_STATE control message. Signed-off-by: Jeroen Hofstee Link: https://lore.kernel.org/all/20221019221016.1659260-7-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index e2e23467caf21..3f00e8d79b754 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -66,6 +66,7 @@ enum gs_usb_breq { GS_USB_BREQ_BT_CONST_EXT, GS_USB_BREQ_SET_TERMINATION, GS_USB_BREQ_GET_TERMINATION, + GS_USB_BREQ_GET_STATE, }; enum gs_can_mode { @@ -135,6 +136,7 @@ struct gs_device_config { /* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */ /* GS_CAN_FEATURE_TERMINATION BIT(11) */ #define GS_CAN_MODE_BERR_REPORTING BIT(12) +/* GS_CAN_FEATURE_GET_STATE BIT(13) */ struct gs_device_mode { __le32 mode; @@ -176,7 +178,8 @@ struct gs_device_termination_state { #define GS_CAN_FEATURE_BT_CONST_EXT BIT(10) #define GS_CAN_FEATURE_TERMINATION BIT(11) #define GS_CAN_FEATURE_BERR_REPORTING BIT(12) -#define GS_CAN_FEATURE_MASK GENMASK(12, 0) +#define GS_CAN_FEATURE_GET_STATE BIT(13) +#define GS_CAN_FEATURE_MASK GENMASK(13, 0) /* internal quirks - keep in GS_CAN_FEATURE space for now */ From 0c9f92a4b795a68c005ebe215f31b2ad7838b9ea Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sun, 28 Aug 2022 12:25:02 +0200 Subject: [PATCH 7/7] can: gs_usb: add support for reading error counters Add support for reading the device state and CAN error counters, using the GS_USB_BREQ_GET_STATE control message, if supported by the device, indicated by the GS_CAN_FEATURE_GET_STATE feature flag. Signed-off-by: Jeroen Hofstee Link: https://lore.kernel.org/all/20221019221016.1659260-8-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 3f00e8d79b754..ccb1a29835a2f 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -961,6 +961,42 @@ static int gs_can_open(struct net_device *netdev) return 0; } +static int gs_usb_get_state(const struct net_device *netdev, + struct can_berr_counter *bec, + enum can_state *state) +{ + struct gs_can *dev = netdev_priv(netdev); + struct gs_device_state ds; + int rc; + + rc = usb_control_msg_recv(interface_to_usbdev(dev->iface), 0, + GS_USB_BREQ_GET_STATE, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + dev->channel, 0, + &ds, sizeof(ds), + USB_CTRL_GET_TIMEOUT, + GFP_KERNEL); + if (rc) + return rc; + + if (le32_to_cpu(ds.state) >= CAN_STATE_MAX) + return -EOPNOTSUPP; + + *state = le32_to_cpu(ds.state); + bec->txerr = le32_to_cpu(ds.txerr); + bec->rxerr = le32_to_cpu(ds.rxerr); + + return 0; +} + +static int gs_usb_can_get_berr_counter(const struct net_device *netdev, + struct can_berr_counter *bec) +{ + enum can_state state; + + return gs_usb_get_state(netdev, bec, &state); +} + static int gs_can_close(struct net_device *netdev) { int rc; @@ -1235,6 +1271,9 @@ static struct gs_can *gs_make_candev(unsigned int channel, if (feature & GS_CAN_FEATURE_BERR_REPORTING) dev->can.ctrlmode_supported |= CAN_CTRLMODE_BERR_REPORTING; + if (feature & GS_CAN_FEATURE_GET_STATE) + dev->can.do_get_berr_counter = gs_usb_can_get_berr_counter; + /* The CANtact Pro from LinkLayer Labs is based on the * LPC54616 µC, which is affected by the NXP LPC USB transfer * erratum. However, the current firmware (version 2) doesn't