All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Kleine-Budde <mkl@pengutronix.de>
To: linux-can@vger.kernel.org
Cc: kernel@pengutronix.de, "Peter Fink" <pfink@christ-es.de>,
	"Christoph Möhring" <cmoehring@christ-es.de>,
	"Alexander Schartner" <aschartner@christ-es.de>,
	"Marc Kleine-Budde" <mkl@pengutronix.de>
Subject: [can-next-rfc 16/21] can: gs_usb: add usb quirk for NXP LPC546xx controllers
Date: Wed,  9 Mar 2022 13:41:27 +0100	[thread overview]
Message-ID: <20220309124132.291861-17-mkl@pengutronix.de> (raw)
In-Reply-To: <20220309124132.291861-1-mkl@pengutronix.de>

From: Peter Fink <pfink@christ-es.de>

Introduce a workaround for a NXP chip errata on LPC546xx
controllers (Errata sheet LPC546xx / USB.15).

According to the document corruption can occur when the following
conditions are met:
* A TX (IN) transfer happens after a RX (OUT) transfer.
* The RX (OUT) transfer length is 4 + N * 16 (N >= 0) bytes.

Even though the struct gs_host_frame has a size of 76 bytes for a FD
frame, which does not apply to the above rule, corruption could be
seen.

Adding a dummy byte to break the second condition also on transfer
lengths with 4 + N * 8 bytes reliably circumvents USB transfer data
corruption.

The firmware can now request this quirk by setting
GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX.

Signed-off-by: Peter Fink <pfink@christ-es.de>
Signed-off-by: Christoph Möhring <cmoehring@christ-es.de>
Signed-off-by: Alexander Schartner <aschartner@christ-es.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/usb/gs_usb.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index 29389de99326..b0651789ccd3 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -9,6 +9,7 @@
  * Many thanks to all socketcan devs!
  */
 
+#include <linux/bitfield.h>
 #include <linux/ethtool.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -100,6 +101,7 @@ struct gs_device_config {
 /* GS_CAN_FEATURE_USER_ID BIT(6) */
 #define GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
 #define GS_CAN_MODE_FD BIT(8)
+/* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */
 
 struct gs_device_mode {
 	__le32 mode;
@@ -133,6 +135,8 @@ struct gs_identify_mode {
 #define GS_CAN_FEATURE_USER_ID BIT(6)
 #define GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
 #define GS_CAN_FEATURE_FD BIT(8)
+#define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9)
+#define GS_CAN_FEATURE_MASK GENMASK(9, 0)
 
 struct gs_device_bt_const {
 	__le32 feature;
@@ -156,10 +160,20 @@ struct classic_can {
 	u8 data[8];
 } __packed;
 
+struct classic_can_quirk {
+	u8 data[8];
+	u8 quirk;
+} __packed;
+
 struct canfd {
 	u8 data[64];
 } __packed;
 
+struct canfd_quirk {
+	u8 data[64];
+	u8 quirk;
+} __packed;
+
 struct gs_host_frame {
 	u32 echo_id;
 	__le32 can_id;
@@ -171,7 +185,9 @@ struct gs_host_frame {
 
 	union {
 		DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
+		DECLARE_FLEX_ARRAY(struct classic_can_quirk, classic_can_quirk);
 		DECLARE_FLEX_ARRAY(struct canfd, canfd);
+		DECLARE_FLEX_ARRAY(struct canfd_quirk, canfd_quirk);
 	};
 } __packed;
 /* The GS USB devices make use of the same flags and masks as in
@@ -204,6 +220,7 @@ struct gs_can {
 	struct can_bittiming_const bt_const;
 	unsigned int channel;	/* channel number */
 
+	u32 feature;
 	unsigned int hf_size_tx;
 
 	/* This lock prevents a race condition between xmit and receive. */
@@ -666,9 +683,16 @@ static int gs_can_open(struct net_device *netdev)
 	ctrlmode = dev->can.ctrlmode;
 	if (ctrlmode & CAN_CTRLMODE_FD) {
 		flags |= GS_CAN_MODE_FD;
-		dev->hf_size_tx = struct_size(hf, canfd, 1);
+
+		if (dev->feature & GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX)
+			dev->hf_size_tx = struct_size(hf, canfd_quirk, 1);
+		else
+			dev->hf_size_tx = struct_size(hf, canfd, 1);
 	} else {
-		dev->hf_size_tx = struct_size(hf, classic_can, 1);
+		if (dev->feature & GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX)
+			dev->hf_size_tx = struct_size(hf, classic_can_quirk, 1);
+		else
+			dev->hf_size_tx = struct_size(hf, classic_can, 1);
 	}
 
 	if (!parent->active_channels) {
@@ -938,6 +962,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC;
 
 	feature = le32_to_cpu(bt_const->feature);
+	dev->feature = FIELD_GET(GS_CAN_FEATURE_MASK, feature);
 	if (feature & GS_CAN_FEATURE_LISTEN_ONLY)
 		dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
 
-- 
2.34.1



  parent reply	other threads:[~2022-03-09 12:41 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-09 12:41 [RFC]: can-next gs-usb Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 01/21] can: gs_usb: use consistent one space indention Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 02/21] can: gs_usb: fix checkpatch warning Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 03/21] can: gs_usb: sort include files alphabetically Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 04/21] can: gs_usb: GS_CAN_FLAG_OVERFLOW: make use of BIT() Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 05/21] can: gs_usb: rewrap error messages Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 06/21] can: gs_usb: rewrap usb_control_msg() and usb_fill_bulk_urb() Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 07/21] can: gs_usb: gs_make_candev(): call SET_NETDEV_DEV() after handling all bt_const->feature Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 08/21] can: gs_usb: add HW timestamp mode bit Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 09/21] can: gs_usb: update GS_CAN_FEATURE_IDENTIFY documentation Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 10/21] can: gs_usb: document the USER_ID feature Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 11/21] can: gs_usb: document the PAD_PKTS_TO_MAX_PKT_SIZE feature Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 12/21] can: gs_usb: gs_usb_probe(): introduce udev and make use of it Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 13/21] can: gs_usb: support up to 3 channels per device Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 14/21] can: gs_usb: use union and FLEX_ARRAY for data in struct gs_host_frame Marc Kleine-Budde
2022-03-09 14:05   ` Vincent Mailhol
2022-03-09 14:16     ` Vincent Mailhol
2022-03-09 14:20       ` Marc Kleine-Budde
2022-03-09 14:18     ` Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 15/21] can: gs_usb: add CAN-FD support Marc Kleine-Budde
2022-03-09 12:41 ` Marc Kleine-Budde [this message]
2022-03-09 12:41 ` [can-next-rfc 17/21] can: gs_usb: add quirk for CANtact Pro overlapping GS_USB_BREQ value Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 18/21] can: gs_usb: activate quirks for CANtact Pro unconditionally Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 19/21] can: gs_usb: add extended bt_const feature Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 20/21] can: gs_usb: add VID/PID for CES CANext FD devices Marc Kleine-Budde
2022-03-09 12:41 ` [can-next-rfc 21/21] can: gs_usb: add VID/PID for ABE CAN Debugger devices Marc Kleine-Budde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220309124132.291861-17-mkl@pengutronix.de \
    --to=mkl@pengutronix.de \
    --cc=aschartner@christ-es.de \
    --cc=cmoehring@christ-es.de \
    --cc=kernel@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=pfink@christ-es.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.