Commit 8bed3d02 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-next-for-5.18-20220310' of...

Merge tag 'linux-can-next-for-5.18-20220310' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2022-03-10

The first 3 patches are by Oliver Hartkopp, target the CAN ISOTP
protocol and update the CAN frame sending behavior, and increases the
max PDU size to 64 kByte.

The next 2 patches are also by Oliver Hartkopp and update the virtual
VXCAN driver so that CAN frames send into the peer name space show up
as RX'ed CAN frames.

Vincent Mailhol contributes a patch for the etas_es58x driver to fix a
false positive dereference uninitialized variable warning.

2 patches by Ulrich Hecht add r8a779a0 SoC support to the rcar_canfd
driver.

The remaining 21 patches target the gs_usb driver and are by Peter
Fink, Ben Evans, Eric Evenchick and me. This series cleans up the
gs-usb driver, documents some bits of the USB ABI used by the widely
used open source firmware candleLight, adds support for up to 3 CAN
interfaces per USB device, adds CAN-FD support, adds quirks for some
hardware and software workarounds and finally adds support for 2 new
devices.

* tag 'linux-can-next-for-5.18-20220310' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: (29 commits)
  can: gs_usb: add VID/PID for ABE CAN Debugger devices
  can: gs_usb: add VID/PID for CES CANext FD devices
  can: gs_usb: add extended bt_const feature
  can: gs_usb: activate quirks for CANtact Pro unconditionally
  can: gs_usb: add quirk for CANtact Pro overlapping GS_USB_BREQ value
  can: gs_usb: add usb quirk for NXP LPC546xx controllers
  can: gs_usb: add CAN-FD support
  can: gs_usb: use union and FLEX_ARRAY for data in struct gs_host_frame
  can: gs_usb: support up to 3 channels per device
  can: gs_usb: gs_usb_probe(): introduce udev and make use of it
  can: gs_usb: document the PAD_PKTS_TO_MAX_PKT_SIZE feature
  can: gs_usb: document the USER_ID feature
  can: gs_usb: update GS_CAN_FEATURE_IDENTIFY documentation
  can: gs_usb: add HW timestamp mode bit
  can: gs_usb: gs_make_candev(): call SET_NETDEV_DEV() after handling all bt_const->feature
  can: gs_usb: rewrap usb_control_msg() and usb_fill_bulk_urb()
  can: gs_usb: rewrap error messages
  can: gs_usb: GS_CAN_FLAG_OVERFLOW: make use of BIT()
  can: gs_usb: sort include files alphabetically
  can: gs_usb: fix checkpatch warning
  ...
====================

Link: https://lore.kernel.org/r/20220310142903.341658-1-mkl@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1e8a3f0d 0691a4b5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ properties:
              - renesas,r9a07g044-canfd    # RZ/G2{L,LC}
          - const: renesas,rzg2l-canfd     # RZ/G2L family

      - const: renesas,r8a779a0-canfd      # R-Car V3U

  reg:
    maxItems: 1

+217 −136

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
@@ -173,12 +173,11 @@ static int es58x_fd_rx_event_msg(struct net_device *netdev,
	const struct es58x_fd_rx_event_msg *rx_event_msg;
	int ret;

	rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg;
	ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len);
	if (ret)
		return ret;

	rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg;

	return es58x_rx_err_msg(netdev, rx_event_msg->error_code,
				rx_event_msg->event_code,
				get_unaligned_le64(&rx_event_msg->timestamp));
+326 −120
Original line number Diff line number Diff line
@@ -9,11 +9,12 @@
 * Many thanks to all socketcan devs!
 */

#include <linux/bitfield.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/signal.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/signal.h>
#include <linux/usb.h>

#include <linux/can.h>
@@ -27,6 +28,12 @@
#define USB_CANDLELIGHT_VENDOR_ID 0x1209
#define USB_CANDLELIGHT_PRODUCT_ID 0x2323

#define USB_CES_CANEXT_FD_VENDOR_ID 0x1cd2
#define USB_CES_CANEXT_FD_PRODUCT_ID 0x606f

#define USB_ABE_CANDEBUGGER_FD_VENDOR_ID 0x16d0
#define USB_ABE_CANDEBUGGER_FD_PRODUCT_ID 0x10b8

#define GSUSB_ENDPOINT_IN 1
#define GSUSB_ENDPOINT_OUT 2

@@ -40,6 +47,11 @@ enum gs_usb_breq {
	GS_USB_BREQ_DEVICE_CONFIG,
	GS_USB_BREQ_TIMESTAMP,
	GS_USB_BREQ_IDENTIFY,
	GS_USB_BREQ_GET_USER_ID,
	GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING = GS_USB_BREQ_GET_USER_ID,
	GS_USB_BREQ_SET_USER_ID,
	GS_USB_BREQ_DATA_BITTIMING,
	GS_USB_BREQ_BT_CONST_EXT,
};

enum gs_can_mode {
@@ -92,6 +104,13 @@ struct gs_device_config {
#define GS_CAN_MODE_LOOP_BACK BIT(1)
#define GS_CAN_MODE_TRIPLE_SAMPLE BIT(2)
#define GS_CAN_MODE_ONE_SHOT BIT(3)
#define GS_CAN_MODE_HW_TIMESTAMP BIT(4)
/* GS_CAN_FEATURE_IDENTIFY BIT(5) */
/* 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) */
/* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */

struct gs_device_mode {
	__le32 mode;
@@ -122,6 +141,19 @@ struct gs_identify_mode {
#define GS_CAN_FEATURE_ONE_SHOT BIT(3)
#define GS_CAN_FEATURE_HW_TIMESTAMP BIT(4)
#define GS_CAN_FEATURE_IDENTIFY BIT(5)
#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_BT_CONST_EXT BIT(10)
#define GS_CAN_FEATURE_MASK GENMASK(10, 0)

/* internal quirks - keep in GS_CAN_FEATURE space for now */

/* CANtact Pro original firmware:
 * BREQ DATA_BITTIMING overlaps with GET_USER_ID
 */
#define GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO BIT(31)

struct gs_device_bt_const {
	__le32 feature;
@@ -136,7 +168,50 @@ struct gs_device_bt_const {
	__le32 brp_inc;
} __packed;

#define GS_CAN_FLAG_OVERFLOW 1
struct gs_device_bt_const_extended {
	__le32 feature;
	__le32 fclk_can;
	__le32 tseg1_min;
	__le32 tseg1_max;
	__le32 tseg2_min;
	__le32 tseg2_max;
	__le32 sjw_max;
	__le32 brp_min;
	__le32 brp_max;
	__le32 brp_inc;

	__le32 dtseg1_min;
	__le32 dtseg1_max;
	__le32 dtseg2_min;
	__le32 dtseg2_max;
	__le32 dsjw_max;
	__le32 dbrp_min;
	__le32 dbrp_max;
	__le32 dbrp_inc;
} __packed;

#define GS_CAN_FLAG_OVERFLOW BIT(0)
#define GS_CAN_FLAG_FD BIT(1)
#define GS_CAN_FLAG_BRS BIT(2)
#define GS_CAN_FLAG_ESI BIT(3)

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;
@@ -147,7 +222,12 @@ struct gs_host_frame {
	u8 flags;
	u8 reserved;

	u8 data[8];
	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
 * linux/can.h and linux/can/error.h, and no additional mapping is necessary.
@@ -158,9 +238,9 @@ struct gs_host_frame {
/* Only launch a max of GS_MAX_RX_URBS usb requests at a time. */
#define GS_MAX_RX_URBS 30
/* Maximum number of interfaces the driver supports per device.
 * Current hardware only supports 2 interfaces. The future may vary.
 * Current hardware only supports 3 interfaces. The future may vary.
 */
#define GS_MAX_INTF 2
#define GS_MAX_INTF 3

struct gs_tx_context {
	struct gs_can *dev;
@@ -176,9 +256,12 @@ struct gs_can {
	struct usb_device *udev;
	struct usb_interface *iface;

	struct can_bittiming_const bt_const;
	struct can_bittiming_const bt_const, data_bt_const;
	unsigned int channel;	/* channel number */

	u32 feature;
	unsigned int hf_size_tx;

	/* This lock prevents a race condition between xmit and receive. */
	spinlock_t tx_ctx_lock;
	struct gs_tx_context tx_context[GS_MAX_TX_URBS];
@@ -192,6 +275,7 @@ struct gs_usb {
	struct gs_can *canch[GS_MAX_INTF];
	struct usb_anchor rx_submitted;
	struct usb_device *udev;
	unsigned int hf_size_rx;
	u8 active_channels;
};

@@ -258,11 +342,7 @@ static int gs_cmd_reset(struct gs_can *gsdev)
			     usb_sndctrlpipe(interface_to_usbdev(intf), 0),
			     GS_USB_BREQ_MODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     gsdev->channel,
			     0,
			     dm,
			     sizeof(*dm),
			     1000);
			     gsdev->channel, 0, dm, sizeof(*dm), 1000);

	kfree(dm);

@@ -304,6 +384,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
	struct gs_host_frame *hf = urb->transfer_buffer;
	struct gs_tx_context *txc;
	struct can_frame *cf;
	struct canfd_frame *cfd;
	struct sk_buff *skb;

	BUG_ON(!usbcan);
@@ -332,18 +413,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
		return;

	if (hf->echo_id == -1) { /* normal rx */
		if (hf->flags & GS_CAN_FLAG_FD) {
			skb = alloc_canfd_skb(dev->netdev, &cfd);
			if (!skb)
				return;

			cfd->can_id = le32_to_cpu(hf->can_id);
			cfd->len = can_fd_dlc2len(hf->can_dlc);
			if (hf->flags & GS_CAN_FLAG_BRS)
				cfd->flags |= CANFD_BRS;
			if (hf->flags & GS_CAN_FLAG_ESI)
				cfd->flags |= CANFD_ESI;

			memcpy(cfd->data, hf->canfd->data, cfd->len);
		} else {
			skb = alloc_can_skb(dev->netdev, &cf);
			if (!skb)
				return;

			cf->can_id = le32_to_cpu(hf->can_id);

			can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
		memcpy(cf->data, hf->data, 8);

			memcpy(cf->data, hf->classic_can->data, 8);

			/* ERROR frames tell us information about the controller */
			if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
				gs_update_state(dev, cf);
		}

		netdev->stats.rx_packets++;
		netdev->stats.rx_bytes += hf->can_dlc;
@@ -392,14 +488,10 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
	}

 resubmit_urb:
	usb_fill_bulk_urb(urb,
			  usbcan->udev,
	usb_fill_bulk_urb(urb, usbcan->udev,
			  usb_rcvbulkpipe(usbcan->udev, GSUSB_ENDPOINT_IN),
			  hf,
			  sizeof(struct gs_host_frame),
			  gs_usb_receive_bulk_callback,
			  usbcan
			  );
			  hf, dev->parent->hf_size_rx,
			  gs_usb_receive_bulk_callback, usbcan);

	rc = usb_submit_urb(urb, GFP_ATOMIC);

@@ -436,11 +528,7 @@ static int gs_usb_set_bittiming(struct net_device *netdev)
			     usb_sndctrlpipe(interface_to_usbdev(intf), 0),
			     GS_USB_BREQ_BITTIMING,
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     dev->channel,
			     0,
			     dbt,
			     sizeof(*dbt),
			     1000);
			     dev->channel, 0, dbt, sizeof(*dbt), 1000);

	kfree(dbt);

@@ -451,6 +539,44 @@ static int gs_usb_set_bittiming(struct net_device *netdev)
	return (rc > 0) ? 0 : rc;
}

static int gs_usb_set_data_bittiming(struct net_device *netdev)
{
	struct gs_can *dev = netdev_priv(netdev);
	struct can_bittiming *bt = &dev->can.data_bittiming;
	struct usb_interface *intf = dev->iface;
	struct gs_device_bittiming *dbt;
	u8 request = GS_USB_BREQ_DATA_BITTIMING;
	int rc;

	dbt = kmalloc(sizeof(*dbt), GFP_KERNEL);
	if (!dbt)
		return -ENOMEM;

	dbt->prop_seg = cpu_to_le32(bt->prop_seg);
	dbt->phase_seg1 = cpu_to_le32(bt->phase_seg1);
	dbt->phase_seg2 = cpu_to_le32(bt->phase_seg2);
	dbt->sjw = cpu_to_le32(bt->sjw);
	dbt->brp = cpu_to_le32(bt->brp);

	if (dev->feature & GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO)
		request = GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING;

	/* request bit timings */
	rc = usb_control_msg(interface_to_usbdev(intf),
			     usb_sndctrlpipe(interface_to_usbdev(intf), 0),
			     request,
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     dev->channel, 0, dbt, sizeof(*dbt), 1000);

	kfree(dbt);

	if (rc < 0)
		dev_err(netdev->dev.parent,
			"Couldn't set data bittimings (err=%d)", rc);

	return (rc > 0) ? 0 : rc;
}

static void gs_usb_xmit_callback(struct urb *urb)
{
	struct gs_tx_context *txc = urb->context;
@@ -460,10 +586,8 @@ static void gs_usb_xmit_callback(struct urb *urb)
	if (urb->status)
		netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);

	usb_free_coherent(urb->dev,
			  urb->transfer_buffer_length,
			  urb->transfer_buffer,
			  urb->transfer_dma);
	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
			  urb->transfer_buffer, urb->transfer_dma);
}

static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
@@ -474,6 +598,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
	struct urb *urb;
	struct gs_host_frame *hf;
	struct can_frame *cf;
	struct canfd_frame *cfd;
	int rc;
	unsigned int idx;
	struct gs_tx_context *txc;
@@ -491,7 +616,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
	if (!urb)
		goto nomem_urb;

	hf = usb_alloc_coherent(dev->udev, sizeof(*hf), GFP_ATOMIC,
	hf = usb_alloc_coherent(dev->udev, dev->hf_size_tx, GFP_ATOMIC,
				&urb->transfer_dma);
	if (!hf) {
		netdev_err(netdev, "No memory left for USB buffer\n");
@@ -510,19 +635,31 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
	hf->flags = 0;
	hf->reserved = 0;

	if (can_is_canfd_skb(skb)) {
		cfd = (struct canfd_frame *)skb->data;

		hf->can_id = cpu_to_le32(cfd->can_id);
		hf->can_dlc = can_fd_len2dlc(cfd->len);
		hf->flags |= GS_CAN_FLAG_FD;
		if (cfd->flags & CANFD_BRS)
			hf->flags |= GS_CAN_FLAG_BRS;
		if (cfd->flags & CANFD_ESI)
			hf->flags |= GS_CAN_FLAG_ESI;

		memcpy(hf->canfd->data, cfd->data, cfd->len);
	} else {
		cf = (struct can_frame *)skb->data;

		hf->can_id = cpu_to_le32(cf->can_id);
		hf->can_dlc = can_get_cc_dlc(cf, dev->can.ctrlmode);

	memcpy(hf->data, cf->data, cf->len);
		memcpy(hf->classic_can->data, cf->data, cf->len);
	}

	usb_fill_bulk_urb(urb, dev->udev,
			  usb_sndbulkpipe(dev->udev, GSUSB_ENDPOINT_OUT),
			  hf,
			  sizeof(*hf),
			  gs_usb_xmit_callback,
			  txc);
			  hf, dev->hf_size_tx,
			  gs_usb_xmit_callback, txc);

	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	usb_anchor_urb(urb, &dev->tx_submitted);
@@ -539,10 +676,8 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
		gs_free_tx_context(txc);

		usb_unanchor_urb(urb);
		usb_free_coherent(dev->udev,
				  sizeof(*hf),
				  hf,
				  urb->transfer_dma);
		usb_free_coherent(dev->udev, urb->transfer_buffer_length,
				  urb->transfer_buffer, urb->transfer_dma);

		if (rc == -ENODEV) {
			netif_device_detach(netdev);
@@ -562,10 +697,8 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
	return NETDEV_TX_OK;

 badidx:
	usb_free_coherent(dev->udev,
			  sizeof(*hf),
			  hf,
			  urb->transfer_dma);
	usb_free_coherent(dev->udev, urb->transfer_buffer_length,
			  urb->transfer_buffer, urb->transfer_dma);
 nomem_hf:
	usb_free_urb(urb);

@@ -582,6 +715,7 @@ static int gs_can_open(struct net_device *netdev)
	struct gs_usb *parent = dev->parent;
	int rc, i;
	struct gs_device_mode *dm;
	struct gs_host_frame *hf;
	u32 ctrlmode;
	u32 flags = 0;

@@ -589,6 +723,21 @@ static int gs_can_open(struct net_device *netdev)
	if (rc)
		return rc;

	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
			dev->hf_size_tx = struct_size(hf, canfd, 1);
	} else {
		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) {
		for (i = 0; i < GS_MAX_RX_URBS; i++) {
			struct urb *urb;
@@ -601,7 +750,7 @@ static int gs_can_open(struct net_device *netdev)

			/* alloc rx buffer */
			buf = usb_alloc_coherent(dev->udev,
						 sizeof(struct gs_host_frame),
						 dev->parent->hf_size_rx,
						 GFP_KERNEL,
						 &urb->transfer_dma);
			if (!buf) {
@@ -617,9 +766,8 @@ static int gs_can_open(struct net_device *netdev)
					  usb_rcvbulkpipe(dev->udev,
							  GSUSB_ENDPOINT_IN),
					  buf,
					  sizeof(struct gs_host_frame),
					  gs_usb_receive_bulk_callback,
					  parent);
					  dev->parent->hf_size_rx,
					  gs_usb_receive_bulk_callback, parent);
			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

			usb_anchor_urb(urb, &parent->rx_submitted);
@@ -630,8 +778,7 @@ static int gs_can_open(struct net_device *netdev)
					netif_device_detach(dev->netdev);

				netdev_err(netdev,
					   "usb_submit failed (err=%d)\n",
					   rc);
					   "usb_submit failed (err=%d)\n", rc);

				usb_unanchor_urb(urb);
				usb_free_urb(urb);
@@ -650,8 +797,6 @@ static int gs_can_open(struct net_device *netdev)
		return -ENOMEM;

	/* flags */
	ctrlmode = dev->can.ctrlmode;

	if (ctrlmode & CAN_CTRLMODE_LOOPBACK)
		flags |= GS_CAN_MODE_LOOP_BACK;
	else if (ctrlmode & CAN_CTRLMODE_LISTENONLY)
@@ -672,13 +817,8 @@ static int gs_can_open(struct net_device *netdev)
	rc = usb_control_msg(interface_to_usbdev(dev->iface),
			     usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0),
			     GS_USB_BREQ_MODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_INTERFACE,
			     dev->channel,
			     0,
			     dm,
			     sizeof(*dm),
			     1000);
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     dev->channel, 0, dm, sizeof(*dm), 1000);

	if (rc < 0) {
		netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
@@ -755,16 +895,10 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
		imode->mode = cpu_to_le32(GS_CAN_IDENTIFY_OFF);

	rc = usb_control_msg(interface_to_usbdev(dev->iface),
			     usb_sndctrlpipe(interface_to_usbdev(dev->iface),
					     0),
			     usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0),
			     GS_USB_BREQ_IDENTIFY,
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_INTERFACE,
			     dev->channel,
			     0,
			     imode,
			     sizeof(*imode),
			     100);
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     dev->channel, 0, imode, sizeof(*imode), 100);

	kfree(imode);

@@ -803,6 +937,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
	struct net_device *netdev;
	int rc;
	struct gs_device_bt_const *bt_const;
	struct gs_device_bt_const_extended *bt_const_extended;
	u32 feature;

	bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL);
@@ -814,11 +949,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
			     usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
			     GS_USB_BREQ_BT_CONST,
			     USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     channel,
			     0,
			     bt_const,
			     sizeof(*bt_const),
			     1000);
			     channel, 0, bt_const, sizeof(*bt_const), 1000);

	if (rc < 0) {
		dev_err(&intf->dev,
@@ -875,6 +1006,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;

@@ -887,7 +1019,37 @@ static struct gs_can *gs_make_candev(unsigned int channel,
	if (feature & GS_CAN_FEATURE_ONE_SHOT)
		dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;

	SET_NETDEV_DEV(netdev, &intf->dev);
	if (feature & GS_CAN_FEATURE_FD) {
		dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
		/* The data bit timing will be overwritten, if
		 * GS_CAN_FEATURE_BT_CONST_EXT is set.
		 */
		dev->can.data_bittiming_const = &dev->bt_const;
		dev->can.do_set_data_bittiming = gs_usb_set_data_bittiming;
	}

	/* 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
	 * set the GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX bit. Set the
	 * feature GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX to workaround
	 * this issue.
	 *
	 * For the GS_USB_BREQ_DATA_BITTIMING USB control message the
	 * CANtact Pro firmware uses a request value, which is already
	 * used by the candleLight firmware for a different purpose
	 * (GS_USB_BREQ_GET_USER_ID). Set the feature
	 * GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO to workaround this
	 * issue.
	 */
	if (dev->udev->descriptor.idVendor == cpu_to_le16(USB_GSUSB_1_VENDOR_ID) &&
	    dev->udev->descriptor.idProduct == cpu_to_le16(USB_GSUSB_1_PRODUCT_ID) &&
	    dev->udev->manufacturer && dev->udev->product &&
	    !strcmp(dev->udev->manufacturer, "LinkLayer Labs") &&
	    !strcmp(dev->udev->product, "CANtact Pro") &&
	    (le32_to_cpu(dconf->sw_version) <= 2))
		dev->feature |= GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX |
			GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO;

	if (le32_to_cpu(dconf->sw_version) > 1)
		if (feature & GS_CAN_FEATURE_IDENTIFY)
@@ -895,6 +1057,45 @@ static struct gs_can *gs_make_candev(unsigned int channel,

	kfree(bt_const);

	/* fetch extended bit timing constants if device has feature
	 * GS_CAN_FEATURE_FD and GS_CAN_FEATURE_BT_CONST_EXT
	 */
	if (feature & GS_CAN_FEATURE_FD &&
	    feature & GS_CAN_FEATURE_BT_CONST_EXT) {
		bt_const_extended = kmalloc(sizeof(*bt_const_extended), GFP_KERNEL);
		if (!bt_const_extended)
			return ERR_PTR(-ENOMEM);

		rc = usb_control_msg(interface_to_usbdev(intf),
				     usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
				     GS_USB_BREQ_BT_CONST_EXT,
				     USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
				     channel, 0, bt_const_extended,
				     sizeof(*bt_const_extended),
				     1000);
		if (rc < 0) {
			dev_err(&intf->dev,
				"Couldn't get extended bit timing const for channel (err=%d)\n",
				rc);
			kfree(bt_const_extended);
			return ERR_PTR(rc);
		}

		strcpy(dev->data_bt_const.name, "gs_usb");
		dev->data_bt_const.tseg1_min = le32_to_cpu(bt_const_extended->dtseg1_min);
		dev->data_bt_const.tseg1_max = le32_to_cpu(bt_const_extended->dtseg1_max);
		dev->data_bt_const.tseg2_min = le32_to_cpu(bt_const_extended->dtseg2_min);
		dev->data_bt_const.tseg2_max = le32_to_cpu(bt_const_extended->dtseg2_max);
		dev->data_bt_const.sjw_max = le32_to_cpu(bt_const_extended->dsjw_max);
		dev->data_bt_const.brp_min = le32_to_cpu(bt_const_extended->dbrp_min);
		dev->data_bt_const.brp_max = le32_to_cpu(bt_const_extended->dbrp_max);
		dev->data_bt_const.brp_inc = le32_to_cpu(bt_const_extended->dbrp_inc);

		dev->can.data_bittiming_const = &dev->data_bt_const;
	}

	SET_NETDEV_DEV(netdev, &intf->dev);

	rc = register_candev(dev->netdev);
	if (rc) {
		free_candev(dev->netdev);
@@ -915,6 +1116,8 @@ static void gs_destroy_candev(struct gs_can *dev)
static int gs_usb_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct gs_host_frame *hf;
	struct gs_usb *dev;
	int rc = -ENOMEM;
	unsigned int icount, i;
@@ -928,21 +1131,16 @@ static int gs_usb_probe(struct usb_interface *intf,
	hconf->byte_order = cpu_to_le32(0x0000beef);

	/* send host config */
	rc = usb_control_msg(interface_to_usbdev(intf),
			     usb_sndctrlpipe(interface_to_usbdev(intf), 0),
	rc = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			     GS_USB_BREQ_HOST_FORMAT,
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     1,
			     intf->cur_altsetting->desc.bInterfaceNumber,
			     hconf,
			     sizeof(*hconf),
			     1000);
			     1, intf->cur_altsetting->desc.bInterfaceNumber,
			     hconf, sizeof(*hconf), 1000);

	kfree(hconf);

	if (rc < 0) {
		dev_err(&intf->dev, "Couldn't send data format (err=%d)\n",
			rc);
		dev_err(&intf->dev, "Couldn't send data format (err=%d)\n", rc);
		return rc;
	}

@@ -951,15 +1149,11 @@ static int gs_usb_probe(struct usb_interface *intf,
		return -ENOMEM;

	/* read device config */
	rc = usb_control_msg(interface_to_usbdev(intf),
			     usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
	rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
			     GS_USB_BREQ_DEVICE_CONFIG,
			     USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			     1,
			     intf->cur_altsetting->desc.bInterfaceNumber,
			     dconf,
			     sizeof(*dconf),
			     1000);
			     1, intf->cur_altsetting->desc.bInterfaceNumber,
			     dconf, sizeof(*dconf), 1000);
	if (rc < 0) {
		dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n",
			rc);
@@ -985,9 +1179,13 @@ static int gs_usb_probe(struct usb_interface *intf,
	}

	init_usb_anchor(&dev->rx_submitted);
	/* default to classic CAN, switch to CAN-FD if at least one of
	 * our channels support CAN-FD.
	 */
	dev->hf_size_rx = struct_size(hf, classic_can, 1);

	usb_set_intfdata(intf, dev);
	dev->udev = interface_to_usbdev(intf);
	dev->udev = udev;

	for (i = 0; i < icount; i++) {
		dev->canch[i] = gs_make_candev(i, intf, dconf);
@@ -1006,6 +1204,9 @@ static int gs_usb_probe(struct usb_interface *intf,
			return rc;
		}
		dev->canch[i]->parent = dev;

		if (dev->canch[i]->can.ctrlmode_supported & CAN_CTRLMODE_FD)
			dev->hf_size_rx = struct_size(hf, canfd, 1);
	}

	kfree(dconf);
@@ -1015,8 +1216,9 @@ static int gs_usb_probe(struct usb_interface *intf,

static void gs_usb_disconnect(struct usb_interface *intf)
{
	unsigned i;
	struct gs_usb *dev = usb_get_intfdata(intf);
	unsigned int i;

	usb_set_intfdata(intf, NULL);

	if (!dev) {
@@ -1037,6 +1239,10 @@ static const struct usb_device_id gs_usb_table[] = {
				      USB_GSUSB_1_PRODUCT_ID, 0) },
	{ USB_DEVICE_INTERFACE_NUMBER(USB_CANDLELIGHT_VENDOR_ID,
				      USB_CANDLELIGHT_PRODUCT_ID, 0) },
	{ USB_DEVICE_INTERFACE_NUMBER(USB_CES_CANEXT_FD_VENDOR_ID,
				      USB_CES_CANEXT_FD_PRODUCT_ID, 0) },
	{ USB_DEVICE_INTERFACE_NUMBER(USB_ABE_CANDEBUGGER_FD_VENDOR_ID,
				      USB_ABE_CANDEBUGGER_FD_PRODUCT_ID, 0) },
	{} /* Terminating entry */
};

+12 −7
Original line number Diff line number Diff line
@@ -33,28 +33,33 @@ struct vxcan_priv {
	struct net_device __rcu	*peer;
};

static netdev_tx_t vxcan_xmit(struct sk_buff *skb, struct net_device *dev)
static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
{
	struct vxcan_priv *priv = netdev_priv(dev);
	struct net_device *peer;
	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
	struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
	struct net_device_stats *peerstats, *srcstats = &dev->stats;
	struct sk_buff *skb;
	u8 len;

	if (can_dropped_invalid_skb(dev, skb))
	if (can_dropped_invalid_skb(dev, oskb))
		return NETDEV_TX_OK;

	rcu_read_lock();
	peer = rcu_dereference(priv->peer);
	if (unlikely(!peer)) {
		kfree_skb(skb);
		kfree_skb(oskb);
		dev->stats.tx_dropped++;
		goto out_unlock;
	}

	skb = can_create_echo_skb(skb);
	if (!skb)
	skb = skb_clone(oskb, GFP_ATOMIC);
	if (skb) {
		consume_skb(oskb);
	} else {
		kfree(oskb);
		goto out_unlock;
	}

	/* reset CAN GW hop counter */
	skb->csum_start = 0;
@@ -148,7 +153,7 @@ static void vxcan_setup(struct net_device *dev)
	dev->hard_header_len	= 0;
	dev->addr_len		= 0;
	dev->tx_queue_len	= 0;
	dev->flags		= (IFF_NOARP|IFF_ECHO);
	dev->flags		= IFF_NOARP;
	dev->netdev_ops		= &vxcan_netdev_ops;
	dev->needs_free_netdev	= true;

Loading