Hallo Frank, some comments inline. As said in my previous mail, please move the formatting and renaming changes into a separate patch. Can you create an entry in the MAINTAINERS file for the driver (separate patch, too)? On 20.06.2022 22:26:03, Frank Jungclaus wrote: > This patch adds support for the newly available esd CAN-USB/3. > --- > drivers/net/can/usb/esd_usb2.c | 647 ++++++++++++++++++++++++--------- > 1 file changed, 467 insertions(+), 180 deletions(-) > > diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c > index 286daaaea0b8..062f3dd922d2 100644 > --- a/drivers/net/can/usb/esd_usb2.c > +++ b/drivers/net/can/usb/esd_usb2.c > @@ -1,9 +1,11 @@ > // SPDX-License-Identifier: GPL-2.0-only > /* > - * CAN driver for esd CAN-USB/2 and CAN-USB/Micro > + * CAN driver for esd CAN-USB/2, CAN-USB/3 and CAN-USB/Micro > * > - * Copyright (C) 2010-2012 Matthias Fuchs <matthias.fuchs@xxxxxx>, esd gmbh > + * Copyright (C) 2010- Matthias Fuchs , esd gmbh > + * Copyright (C) 2022- Frank Jungclaus <frank.jungclaus@xxxxxx>, esd gmbh The copyright with a starting year, a dash "-", and no end year looks unfamiliar. > */ > + > #include <linux/signal.h> > #include <linux/slab.h> > #include <linux/module.h> > @@ -14,20 +16,25 @@ > #include <linux/can/dev.h> > #include <linux/can/error.h> > > -MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@xxxxxx>"); > -MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces"); > +MODULE_AUTHOR("Frank Jungclaus <frank.jungclaus@xxxxxx>"); > +MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2, CAN-USB/3 and CAN-USB/Micro interfaces"); > MODULE_LICENSE("GPL v2"); Why have you removed the former author? > -/* Define these values to match your devices */ > +/* USB vendor and product ID */ > #define USB_ESDGMBH_VENDOR_ID 0x0ab4 > #define USB_CANUSB2_PRODUCT_ID 0x0010 > #define USB_CANUSBM_PRODUCT_ID 0x0011 > +#define USB_CANUSB3_PRODUCT_ID 0x0014 > > +/* CAN controller clock frequencies */ > #define ESD_USB2_CAN_CLOCK 60000000 > #define ESD_USBM_CAN_CLOCK 36000000 > -#define ESD_USB2_MAX_NETS 2 > +#define ESD_USB3_CAN_CLOCK 80000000 > + > +/* Maximum number of CAN nets */ > +#define ESD_USB_MAX_NETS 2 > > -/* USB2 commands */ > +/* USB commands */ > #define CMD_VERSION 1 /* also used for VERSION_REPLY */ > #define CMD_CAN_RX 2 /* device to host only */ > #define CMD_CAN_TX 3 /* also used for TX_DONE */ > @@ -36,20 +43,29 @@ MODULE_LICENSE("GPL v2"); > #define CMD_IDADD 6 /* also used for IDADD_REPLY */ > > /* esd CAN message flags - dlc field */ > -#define ESD_RTR 0x10 > +#define ESD_DLC_RTR 0x10 > +#define ESD_DLC_NO_BRS 0x10 > +#define ESD_DLC_ESI 0x20 > +#define ESD_DLC_FD 0x80 > + > > /* esd CAN message flags - id field */ > #define ESD_EXTID 0x20000000 > #define ESD_EVENT 0x40000000 > #define ESD_IDMASK 0x1fffffff > > -/* esd CAN event ids used by this driver */ > -#define ESD_EV_CAN_ERROR_EXT 2 > +/* esd CAN event ids */ > +#define ESD_EV_CAN_ERROR 0 /* General bus diagnostics data */ > +#define ESD_EV_BAUD_CHANGE 1 /* Bit rate change event (unused within this driver) */ > +#define ESD_EV_CAN_ERROR_EXT 2 /* CAN controller specific diagnostic data */ > +#define ESD_EV_BUSLOAD 3 /* Busload event (unused within this driver) */ > > -/* baudrate message flags */ > +/* Baudrate message flags */ > #define ESD_USB2_UBR 0x80000000 > #define ESD_USB2_LOM 0x40000000 > #define ESD_USB2_NO_BAUDRATE 0x7fffffff > + > +/* Bit timing CAN-USB/2 */ > #define ESD_USB2_TSEG1_MIN 1 > #define ESD_USB2_TSEG1_MAX 16 > #define ESD_USB2_TSEG1_SHIFT 16 > @@ -64,6 +80,28 @@ MODULE_LICENSE("GPL v2"); > #define ESD_USB2_BRP_INC 1 > #define ESD_USB2_3_SAMPLES 0x00800000 > > +/* Bit timing CAN-USB/3 */ > +#define ESD_USB3_TSEG1_MIN 1 > +#define ESD_USB3_TSEG1_MAX 256 > +#define ESD_USB3_TSEG2_MIN 1 > +#define ESD_USB3_TSEG2_MAX 128 > +#define ESD_USB3_SJW_MAX 128 > +#define ESD_USB3_BRP_MIN 1 > +#define ESD_USB3_BRP_MAX 1024 > +#define ESD_USB3_BRP_INC 1 > +/* Bit timing CAN-USB/3, data phase */ > +#define ESD_USB3_DATA_TSEG1_MIN 1 > +#define ESD_USB3_DATA_TSEG1_MAX 32 > +#define ESD_USB3_DATA_TSEG2_MIN 1 > +#define ESD_USB3_DATA_TSEG2_MAX 16 > +#define ESD_USB3_DATA_SJW_MAX 8 > +#define ESD_USB3_DATA_BRP_MIN 1 > +#define ESD_USB3_DATA_BRP_MAX 32 > +#define ESD_USB3_DATA_BRP_INC 1 > + > +/* Transmitter Delay Compensation */ > +#define ESD_TDC_MODE_AUTO 0 Please do consistent indenting, here you use spaces not tabs. > + > /* esd IDADD message */ > #define ESD_ID_ENABLE 0x80 > #define ESD_MAX_ID_SEGMENT 64 > @@ -78,15 +116,31 @@ MODULE_LICENSE("GPL v2"); > #define SJA1000_ECC_MASK 0xc0 > > /* esd bus state event codes */ > -#define ESD_BUSSTATE_MASK 0xc0 > +#define ESD_BUSSTATE_OK 0x00 > #define ESD_BUSSTATE_WARN 0x40 > #define ESD_BUSSTATE_ERRPASSIVE 0x80 > #define ESD_BUSSTATE_BUSOFF 0xc0 > +#define ESD_BUSSTATE_MASK 0xc0 > > #define RX_BUFFER_SIZE 1024 > #define MAX_RX_URBS 4 > #define MAX_TX_URBS 16 /* must be power of 2 */ > > +/* Modes for NTCAN_BAUDRATE_X */ > +#define ESD_BAUDRATE_MODE_DISABLE 0 /* Remove from bus */ > +#define ESD_BAUDRATE_MODE_INDEX 1 /* ESD (CiA) bit rate idx */ > +#define ESD_BAUDRATE_MODE_BTR_CTRL 2 /* BTR values (Controller)*/ > +#define ESD_BAUDRATE_MODE_BTR_CANONICAL 3 /* BTR values (Canonical) */ > +#define ESD_BAUDRATE_MODE_NUM 4 /* Numerical bit rate */ > +#define ESD_BAUDRATE_MODE_AUTOBAUD 5 /* Autobaud */ > + > +/* Flags for NTCAN_BAUDRATE_X */ > +#define ESD_BAUDRATE_FLAG_FD 0x0001 /* Enable CAN FD Mode */ > +#define ESD_BAUDRATE_FLAG_LOM 0x0002 /* Enable Listen Only mode */ > +#define ESD_BAUDRATE_FLAG_STM 0x0004 /* Enable Self test mode */ > +#define ESD_BAUDRATE_FLAG_TRS 0x0008 /* Enable Triple Sampling */ > +#define ESD_BAUDRATE_FLAG_TXP 0x0010 /* Enable Transmit Pause */ > + > struct header_msg { > u8 len; /* len is always the total message length in 32bit words */ > u8 cmd; > @@ -119,7 +173,10 @@ struct rx_msg { > u8 dlc; > __le32 ts; > __le32 id; /* upper 3 bits contain flags */ > - u8 data[8]; > + union { > + u8 cc[8]; /* classic CAN */ > + u8 fd[64]; /* CAN FD */ > + } data; > }; > > struct tx_msg { > @@ -127,9 +184,12 @@ struct tx_msg { > u8 cmd; > u8 net; > u8 dlc; > - u32 hnd; /* opaque handle, not used by device */ > + u32 hnd; /* opaque handle, not used by device */ > __le32 id; /* upper 3 bits contain flags */ > - u8 data[8]; > + union { > + u8 cc[8]; /* classic CAN */ > + u8 fd[64]; /* CAN FD */ > + } data; > }; > > struct tx_done_msg { > @@ -149,16 +209,41 @@ struct id_filter_msg { > __le32 mask[ESD_MAX_ID_SEGMENT + 1]; > }; > > +struct baudrate_x_cfg { > + __le16 brp; /* Bit rate pre-scaler */ > + __le16 tseg1; /* TSEG1 register */ > + __le16 tseg2; /* TSEG2 register */ > + __le16 sjw; /* SJW register */ > +}; > + > +struct tdc_cfg { > + u8 tdc_mode; /* Transmitter Delay Compensation mode */ > + u8 ssp_offset; /* Secondary Sample Point offset in mtq */ > + s8 ssp_shift; /* Secondary Sample Point shift in mtq */ > + u8 tdc_filter; /* Transmitter Delay Compensation */ > +}; > + > +struct baudrate_x { Nitpick: The tdc_cfg struct has a nice name, IMHO "baudrate_x" deserves a nice name, too. > + __le16 mode; /* Mode word */ > + __le16 flags; /* Control flags */ > + struct tdc_cfg tdc; /* TDC configuration */ > + struct baudrate_x_cfg arb; /* Bit rate during arbitration phase */ > + struct baudrate_x_cfg data; /* Bit rate during data phase */ > +}; > + > struct set_baudrate_msg { > u8 len; > u8 cmd; > u8 net; > u8 rsvd; > - __le32 baud; > + union { > + __le32 baud; > + struct baudrate_x baud_x; > + } u; BTW: you can use an anonymous union here, remove the "u" the you can access the members directly, e.g.: struct set_baudrate_msg { u8 len; u8 cmd; u8 net; u8 rsvd; __le32 baud; union { __le32 baud; struct baudrate_x baud_x; }; }; struct set_baudrate_msg *foo; foo->baud = 10; > }; > > /* Main message type used between library and application */ > -struct __attribute__ ((packed)) esd_usb2_msg { > +struct __packed esd_usb_msg { > union { > struct header_msg hdr; > struct version_msg version; > @@ -171,23 +256,24 @@ struct __attribute__ ((packed)) esd_usb2_msg { > } msg; > }; > > -static struct usb_device_id esd_usb2_table[] = { > +static struct usb_device_id esd_usb_table[] = { > {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB2_PRODUCT_ID)}, > {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSBM_PRODUCT_ID)}, > + {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB3_PRODUCT_ID)}, > {} > }; > -MODULE_DEVICE_TABLE(usb, esd_usb2_table); > +MODULE_DEVICE_TABLE(usb, esd_usb_table); > > -struct esd_usb2_net_priv; > +struct esd_usb_net_priv; > > struct esd_tx_urb_context { > - struct esd_usb2_net_priv *priv; > + struct esd_usb_net_priv *priv; > u32 echo_index; > }; > > -struct esd_usb2 { > +struct esd_usb { > struct usb_device *udev; > - struct esd_usb2_net_priv *nets[ESD_USB2_MAX_NETS]; > + struct esd_usb_net_priv *nets[ESD_USB_MAX_NETS]; > > struct usb_anchor rx_submitted; > > @@ -198,36 +284,64 @@ struct esd_usb2 { > dma_addr_t rxbuf_dma[MAX_RX_URBS]; > }; > > -struct esd_usb2_net_priv { > +struct esd_usb_net_priv { > struct can_priv can; /* must be the first member */ > > atomic_t active_tx_jobs; > struct usb_anchor tx_submitted; > struct esd_tx_urb_context tx_contexts[MAX_TX_URBS]; > > - struct esd_usb2 *usb2; > + struct esd_usb *usb; > struct net_device *netdev; > int index; > u8 old_state; > struct can_berr_counter bec; > }; > > -static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, > - struct esd_usb2_msg *msg) > +static void esd_usb_rx_event(struct esd_usb_net_priv *priv, struct esd_usb_msg *msg) > { > struct net_device_stats *stats = &priv->netdev->stats; > struct can_frame *cf; > struct sk_buff *skb; > u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK; > > +#if defined(DEBUG) please remove this debug code > + { > + static struct esd_usb_msg old_msg; > + static u32 rx_event_cnt; > + > + msg->msg.rx.ts = 0; > + if (memcmp(msg, &old_msg, 16)) { > + netdev_info(priv->netdev, > + "EVENT:%08d: id=%#02x dlc=%#02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", > + rx_event_cnt, > + id, > + msg->msg.rx.dlc, > + msg->msg.rx.data.cc[0], > + msg->msg.rx.data.cc[1], > + msg->msg.rx.data.cc[2], > + msg->msg.rx.data.cc[3], > + msg->msg.rx.data.cc[4], > + msg->msg.rx.data.cc[5], > + msg->msg.rx.data.cc[6], > + msg->msg.rx.data.cc[7]); > + memcpy(&old_msg, msg, 16); > + } > + rx_event_cnt++; > + } > +#endif /* DEBUG */ > + > if (id == ESD_EV_CAN_ERROR_EXT) { > - u8 state = msg->msg.rx.data[0]; > - u8 ecc = msg->msg.rx.data[1]; > - u8 rxerr = msg->msg.rx.data[2]; > - u8 txerr = msg->msg.rx.data[3]; > + /* Here, for ESD_EV_CAN_ERROR_EXT we don't need > + * any special treatment for EVMSG_X > + */ > + u8 state = msg->msg.rx.data.cc[0]; > + u8 ecc = msg->msg.rx.data.cc[1]; > + u8 rxerr = msg->msg.rx.data.cc[2]; > + u8 txerr = msg->msg.rx.data.cc[3]; Can you add a new member to the union that allows easier decoding of the error? > > skb = alloc_can_err_skb(priv->netdev, &cf); > - if (skb == NULL) { > + if (!skb) { > stats->rx_dropped++; > return; > } > @@ -280,7 +394,7 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, > cf->data[2] |= CAN_ERR_PROT_TX; > > if (priv->can.state == CAN_STATE_ERROR_WARNING || > - priv->can.state == CAN_STATE_ERROR_PASSIVE) { > + priv->can.state == CAN_STATE_ERROR_PASSIVE) { > cf->data[1] = (txerr > rxerr) ? > CAN_ERR_CRTL_TX_PASSIVE : > CAN_ERR_CRTL_RX_PASSIVE; > @@ -293,16 +407,40 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, > priv->bec.rxerr = rxerr; > > netif_rx(skb); > + > + } else if (id == ESD_EV_CAN_ERROR) { > + u8 state = msg->msg.rx.data.cc[1]; > + > + /* Switching back to Error Warn and back to Error Passive > + * only is announced by means of a non-extended Error Event ... > + */ > + switch (state & ESD_BUSSTATE_MASK) { > + case ESD_BUSSTATE_OK: > + priv->old_state = state; > + priv->can.state = CAN_STATE_ERROR_ACTIVE; > + priv->bec.txerr = 0; > + priv->bec.rxerr = 0; > + break; > + case ESD_BUSSTATE_WARN: > + /* ... intentionally, don't set priv->old_state here! */ > + priv->can.state = CAN_STATE_ERROR_WARNING; > + break; > + default: > + /* Do nothing ... */ > + break; > + } > } > } > > -static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, > - struct esd_usb2_msg *msg) > +static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, struct esd_usb_msg *msg) > { > struct net_device_stats *stats = &priv->netdev->stats; > - struct can_frame *cf; > + /* can.h: > + * ... the struct can_frame and struct canfd_frame intentionally > + * share the same layout ... > + */ Please remove this comment. > + struct canfd_frame *cfd; > struct sk_buff *skb; > - int i; > u32 id; > > if (!netif_device_present(priv->netdev)) > @@ -311,39 +449,63 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, > id = le32_to_cpu(msg->msg.rx.id); > > if (id & ESD_EVENT) { > - esd_usb2_rx_event(priv, msg); > + esd_usb_rx_event(priv, msg); > } else { > - skb = alloc_can_skb(priv->netdev, &cf); > - if (skb == NULL) { > - stats->rx_dropped++; > - return; > - } > > - cf->can_id = id & ESD_IDMASK; > - can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR, > - priv->can.ctrlmode); > + if (msg->msg.rx.dlc & ESD_DLC_FD) { > + /* CAN FD */ > + skb = alloc_canfd_skb(priv->netdev, &cfd); > + if (!skb) { > + stats->rx_dropped++; > + return; > + } > > - if (id & ESD_EXTID) > - cf->can_id |= CAN_EFF_FLAG; > + /* Masking by 0x0F is already done within can_fd_dlc2len()! */ > + cfd->len = can_fd_dlc2len(msg->msg.rx.dlc); > + > + if ((msg->msg.rx.dlc & ESD_DLC_NO_BRS) == 0) > + cfd->flags |= CANFD_BRS; > + > + if (msg->msg.rx.dlc & ESD_DLC_ESI) > + cfd->flags |= CANFD_ESI; > > - if (msg->msg.rx.dlc & ESD_RTR) { > - cf->can_id |= CAN_RTR_FLAG; > + memcpy(cfd->data, msg->msg.rx.data.fd, cfd->len); > + stats->rx_bytes += cfd->len; > } else { > - for (i = 0; i < cf->len; i++) > - cf->data[i] = msg->msg.rx.data[i]; > + /* Classic CAN */ > + skb = alloc_can_skb(priv->netdev, (struct can_frame **)&cfd); > + if (!skb) { > + stats->rx_dropped++; > + return; > + } > > - stats->rx_bytes += cf->len; > + can_frame_set_cc_len((struct can_frame *)cfd, > + msg->msg.rx.dlc & 0x0F, > + priv->can.ctrlmode); > + > + if (msg->msg.rx.dlc & ESD_DLC_RTR) { > + /* No data copy for a RTR frame */ > + cfd->can_id |= CAN_RTR_FLAG; // ok, due to memset(0) > + // in alloc_can_skb() > + } else { > + memcpy(cfd->data, msg->msg.rx.data.cc, cfd->len); > + stats->rx_bytes += cfd->len; > + } > } > - stats->rx_packets++; > > + /* Common part for CAN FD and CAN classic ... */ > + cfd->can_id |= id & ESD_IDMASK; > + > + if (id & ESD_EXTID) > + cfd->can_id |= CAN_EFF_FLAG; > + > + stats->rx_packets++; > netif_rx(skb); > } > > - return; > } > > -static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, > - struct esd_usb2_msg *msg) > +static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, struct esd_usb_msg *msg) > { > struct net_device_stats *stats = &priv->netdev->stats; > struct net_device *netdev = priv->netdev; > @@ -356,8 +518,7 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, > > if (!msg->msg.txdone.status) { > stats->tx_packets++; > - stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index, > - NULL); > + stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index, NULL); > } else { > stats->tx_errors++; > can_free_echo_skb(netdev, context->echo_index, NULL); > @@ -370,9 +531,9 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, > netif_wake_queue(netdev); > } > > -static void esd_usb2_read_bulk_callback(struct urb *urb) > +static void esd_usb_read_bulk_callback(struct urb *urb) > { > - struct esd_usb2 *dev = urb->context; > + struct esd_usb *dev = urb->context; > int retval; > int pos = 0; > int i; > @@ -394,9 +555,9 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) > } > > while (pos < urb->actual_length) { > - struct esd_usb2_msg *msg; > + struct esd_usb_msg *msg; > > - msg = (struct esd_usb2_msg *)(urb->transfer_buffer + pos); > + msg = (struct esd_usb_msg *)(urb->transfer_buffer + pos); > > switch (msg->msg.hdr.cmd) { > case CMD_CAN_RX: > @@ -405,7 +566,7 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) > break; > } > > - esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg); > + esd_usb_rx_can_msg(dev->nets[msg->msg.rx.net], msg); > break; > > case CMD_CAN_TX: > @@ -414,8 +575,7 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) > break; > } > > - esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net], > - msg); > + esd_usb_tx_done_msg(dev->nets[msg->msg.txdone.net], msg); > break; > } > > @@ -429,8 +589,8 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) > > resubmit_urb: > usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), > - urb->transfer_buffer, RX_BUFFER_SIZE, > - esd_usb2_read_bulk_callback, dev); > + urb->transfer_buffer, RX_BUFFER_SIZE, > + esd_usb_read_bulk_callback, dev); > > retval = usb_submit_urb(urb, GFP_ATOMIC); > if (retval == -ENODEV) { > @@ -443,18 +603,17 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) > "failed resubmitting read bulk urb: %d\n", retval); > } > > - return; > } > > /* > * callback for bulk IN urb > */ > -static void esd_usb2_write_bulk_callback(struct urb *urb) > +static void esd_usb_write_bulk_callback(struct urb *urb) > { > struct esd_tx_urb_context *context = urb->context; > - struct esd_usb2_net_priv *priv; > + struct esd_usb_net_priv *priv; > struct net_device *netdev; > - size_t size = sizeof(struct esd_usb2_msg); > + size_t size = sizeof(struct esd_usb_msg); > > WARN_ON(!context); > > @@ -478,7 +637,7 @@ static ssize_t firmware_show(struct device *d, > struct device_attribute *attr, char *buf) > { > struct usb_interface *intf = to_usb_interface(d); > - struct esd_usb2 *dev = usb_get_intfdata(intf); > + struct esd_usb *dev = usb_get_intfdata(intf); > > return sprintf(buf, "%d.%d.%d\n", > (dev->version >> 12) & 0xf, > @@ -491,7 +650,7 @@ static ssize_t hardware_show(struct device *d, > struct device_attribute *attr, char *buf) > { > struct usb_interface *intf = to_usb_interface(d); > - struct esd_usb2 *dev = usb_get_intfdata(intf); > + struct esd_usb *dev = usb_get_intfdata(intf); > > return sprintf(buf, "%d.%d.%d\n", > (dev->version >> 28) & 0xf, > @@ -504,13 +663,13 @@ static ssize_t nets_show(struct device *d, > struct device_attribute *attr, char *buf) > { > struct usb_interface *intf = to_usb_interface(d); > - struct esd_usb2 *dev = usb_get_intfdata(intf); > + struct esd_usb *dev = usb_get_intfdata(intf); > > return sprintf(buf, "%d", dev->net_count); > } > static DEVICE_ATTR_RO(nets); > > -static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg) > +static int esd_usb_send_msg(struct esd_usb *dev, struct esd_usb_msg *msg) > { > int actual_length; > > @@ -522,8 +681,7 @@ static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg) > 1000); > } > > -static int esd_usb2_wait_msg(struct esd_usb2 *dev, > - struct esd_usb2_msg *msg) > +static int esd_usb_wait_msg(struct esd_usb *dev, struct esd_usb_msg *msg) > { > int actual_length; > > @@ -535,7 +693,7 @@ static int esd_usb2_wait_msg(struct esd_usb2 *dev, > 1000); > } > > -static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) > +static int esd_usb_setup_rx_urbs(struct esd_usb *dev) > { > int i, err = 0; > > @@ -554,8 +712,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) > break; > } > > - buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, > - &buf_dma); > + buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, &buf_dma); > if (!buf) { > dev_warn(dev->udev->dev.parent, > "No memory left for USB buffer\n"); > @@ -568,15 +725,14 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) > usb_fill_bulk_urb(urb, dev->udev, > usb_rcvbulkpipe(dev->udev, 1), > buf, RX_BUFFER_SIZE, > - esd_usb2_read_bulk_callback, dev); > + esd_usb_read_bulk_callback, dev); > urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; > usb_anchor_urb(urb, &dev->rx_submitted); > > err = usb_submit_urb(urb, GFP_KERNEL); > if (err) { > usb_unanchor_urb(urb); > - usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, > - urb->transfer_dma); > + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); > goto freeurb; > } > > @@ -609,11 +765,11 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) > /* > * Start interface > */ > -static int esd_usb2_start(struct esd_usb2_net_priv *priv) > +static int esd_usb_start(struct esd_usb_net_priv *priv) > { > - struct esd_usb2 *dev = priv->usb2; > + struct esd_usb *dev = priv->usb; > struct net_device *netdev = priv->netdev; > - struct esd_usb2_msg *msg; > + struct esd_usb_msg *msg; > int err, i; > > msg = kmalloc(sizeof(*msg), GFP_KERNEL); > @@ -624,7 +780,7 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) > > /* > * Enable all IDs > - * The IDADD message takes up to 64 32 bit bitmasks (2048 bits). > + * The IDADD message takes up to 64 32-bit bitmasks (2048 bits). > * Each bit represents one 11 bit CAN identifier. A set bit > * enables reception of the corresponding CAN identifier. A cleared > * bit disabled this identifier. An additional bitmask value > @@ -641,14 +797,15 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) > msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ > for (i = 0; i < ESD_MAX_ID_SEGMENT; i++) > msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff); > + > /* enable 29bit extended IDs */ > msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); > > - err = esd_usb2_send_msg(dev, msg); > + err = esd_usb_send_msg(dev, msg); > if (err) > goto out; > > - err = esd_usb2_setup_rx_urbs(dev); > + err = esd_usb_setup_rx_urbs(dev); > if (err) > goto out; > > @@ -664,16 +821,16 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) > return err; > } > > -static void unlink_all_urbs(struct esd_usb2 *dev) > +static void unlink_all_urbs(struct esd_usb *dev) > { > - struct esd_usb2_net_priv *priv; > + struct esd_usb_net_priv *priv; > int i, j; > > usb_kill_anchored_urbs(&dev->rx_submitted); > > for (i = 0; i < MAX_RX_URBS; ++i) > - usb_free_coherent(dev->udev, RX_BUFFER_SIZE, > - dev->rxbuf[i], dev->rxbuf_dma[i]); > + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, dev->rxbuf[i], dev->rxbuf_dma[i]); > + > > for (i = 0; i < dev->net_count; i++) { > priv = dev->nets[i]; > @@ -687,9 +844,9 @@ static void unlink_all_urbs(struct esd_usb2 *dev) > } > } > > -static int esd_usb2_open(struct net_device *netdev) > +static int esd_usb_open(struct net_device *netdev) > { > - struct esd_usb2_net_priv *priv = netdev_priv(netdev); > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > int err; > > /* common open */ > @@ -698,7 +855,7 @@ static int esd_usb2_open(struct net_device *netdev) > return err; > > /* finally start device */ > - err = esd_usb2_start(priv); > + err = esd_usb_start(priv); > if (err) { > netdev_warn(netdev, "couldn't start device: %d\n", err); > close_candev(netdev); > @@ -710,20 +867,23 @@ static int esd_usb2_open(struct net_device *netdev) > return 0; > } > > -static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, > - struct net_device *netdev) > +static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) > { > - struct esd_usb2_net_priv *priv = netdev_priv(netdev); > - struct esd_usb2 *dev = priv->usb2; > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > + struct esd_usb *dev = priv->usb; > struct esd_tx_urb_context *context = NULL; > struct net_device_stats *stats = &netdev->stats; > - struct can_frame *cf = (struct can_frame *)skb->data; > - struct esd_usb2_msg *msg; > + /* can.h: > + * ... the struct can_frame and struct canfd_frame intentionally > + * share the same layout ... > + */ > + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; > + struct esd_usb_msg *msg; > struct urb *urb; > u8 *buf; > int i, err; > int ret = NETDEV_TX_OK; > - size_t size = sizeof(struct esd_usb2_msg); > + size_t size = sizeof(struct esd_usb_msg); > > if (can_dropped_invalid_skb(netdev, skb)) > return NETDEV_TX_OK; > @@ -736,8 +896,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, > goto nourbmem; > } > > - buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, > - &urb->transfer_dma); > + buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); > if (!buf) { > netdev_err(netdev, "No memory left for USB buffer\n"); > stats->tx_dropped++; > @@ -745,24 +904,35 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, > goto nobufmem; > } > > - msg = (struct esd_usb2_msg *)buf; > + msg = (struct esd_usb_msg *)buf; > > msg->msg.hdr.len = 3; /* minimal length */ > msg->msg.hdr.cmd = CMD_CAN_TX; > msg->msg.tx.net = priv->index; > - msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode); > - msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK); > > - if (cf->can_id & CAN_RTR_FLAG) > - msg->msg.tx.dlc |= ESD_RTR; > + if (can_is_canfd_skb(skb)) { > + /* CAN FD */ > + msg->msg.tx.dlc = can_fd_len2dlc(cfd->len); > + msg->msg.tx.dlc |= ESD_DLC_FD; > > - if (cf->can_id & CAN_EFF_FLAG) > - msg->msg.tx.id |= cpu_to_le32(ESD_EXTID); > + if ((cfd->flags & CANFD_BRS) == 0) > + msg->msg.tx.dlc |= ESD_DLC_NO_BRS; > + } else { > + /* Classic CAN */ > + msg->msg.tx.dlc = can_get_cc_dlc((struct can_frame *)cfd, priv->can.ctrlmode); > + > + if (cfd->can_id & CAN_RTR_FLAG) > + msg->msg.tx.dlc |= ESD_DLC_RTR; > + } > > - for (i = 0; i < cf->len; i++) > - msg->msg.tx.data[i] = cf->data[i]; > + /* Common for classic CAN and CAN FD */ > + msg->msg.hdr.len += (cfd->len + 3) >> 2; > > - msg->msg.hdr.len += (cf->len + 3) >> 2; > + msg->msg.tx.id = cpu_to_le32(cfd->can_id & CAN_ERR_MASK); > + if (cfd->can_id & CAN_EFF_FLAG) > + msg->msg.tx.id |= cpu_to_le32(ESD_EXTID); > + > + memcpy(msg->msg.tx.data.fd, cfd->data, cfd->len); > > for (i = 0; i < MAX_TX_URBS; i++) { > if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { > @@ -788,7 +958,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, > > usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, > msg->msg.hdr.len << 2, > - esd_usb2_write_bulk_callback, context); > + esd_usb_write_bulk_callback, context); > > urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; > > @@ -839,33 +1009,34 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, > return ret; > } > > -static int esd_usb2_close(struct net_device *netdev) > +static int esd_usb_close(struct net_device *netdev) > { > - struct esd_usb2_net_priv *priv = netdev_priv(netdev); > - struct esd_usb2_msg *msg; > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > + struct esd_usb_msg *msg; > int i; > > msg = kmalloc(sizeof(*msg), GFP_KERNEL); > if (!msg) > return -ENOMEM; > > - /* Disable all IDs (see esd_usb2_start()) */ > + /* Disable all IDs (see esd_usb_start()) */ > msg->msg.hdr.cmd = CMD_IDADD; > msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; > msg->msg.filter.net = priv->index; > msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ > for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) > msg->msg.filter.mask[i] = 0; > - if (esd_usb2_send_msg(priv->usb2, msg) < 0) > + if (esd_usb_send_msg(priv->usb, msg) < 0) > netdev_err(netdev, "sending idadd message failed\n"); > > - /* set CAN controller to reset mode */ > + /* Set CAN controller to reset mode */ > msg->msg.hdr.len = 2; > msg->msg.hdr.cmd = CMD_SETBAUD; > msg->msg.setbaud.net = priv->index; > msg->msg.setbaud.rsvd = 0; > - msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); > - if (esd_usb2_send_msg(priv->usb2, msg) < 0) > + /* Sending ESD_USB2_NO_BAUDRATE is sufficient for CAN-USB/3, even in CAN FD mode, too */ > + msg->msg.setbaud.u.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); > + if (esd_usb_send_msg(priv->usb, msg) < 0) > netdev_err(netdev, "sending setbaud message failed\n"); > > priv->can.state = CAN_STATE_STOPPED; > @@ -879,10 +1050,10 @@ static int esd_usb2_close(struct net_device *netdev) > return 0; > } > > -static const struct net_device_ops esd_usb2_netdev_ops = { > - .ndo_open = esd_usb2_open, > - .ndo_stop = esd_usb2_close, > - .ndo_start_xmit = esd_usb2_start_xmit, > +static const struct net_device_ops esd_usb_netdev_ops = { > + .ndo_open = esd_usb_open, > + .ndo_stop = esd_usb_close, > + .ndo_start_xmit = esd_usb_start_xmit, > .ndo_change_mtu = can_change_mtu, > }; > > @@ -898,11 +1069,35 @@ static const struct can_bittiming_const esd_usb2_bittiming_const = { > .brp_inc = ESD_USB2_BRP_INC, > }; > > +static const struct can_bittiming_const esd_usb3_bittiming_const = { > + .name = "esd_usb3", > + .tseg1_min = ESD_USB3_TSEG1_MIN, > + .tseg1_max = ESD_USB3_TSEG1_MAX, > + .tseg2_min = ESD_USB3_TSEG2_MIN, > + .tseg2_max = ESD_USB3_TSEG2_MAX, > + .sjw_max = ESD_USB3_SJW_MAX, > + .brp_min = ESD_USB3_BRP_MIN, > + .brp_max = ESD_USB3_BRP_MAX, > + .brp_inc = ESD_USB3_BRP_INC, > +}; > + > +static const struct can_bittiming_const esd_usb3_data_bittiming_const = { > + .name = "esd_usb3", > + .tseg1_min = ESD_USB3_DATA_TSEG1_MIN, > + .tseg1_max = ESD_USB3_DATA_TSEG1_MAX, > + .tseg2_min = ESD_USB3_DATA_TSEG2_MIN, > + .tseg2_max = ESD_USB3_DATA_TSEG2_MAX, > + .sjw_max = ESD_USB3_DATA_SJW_MAX, > + .brp_min = ESD_USB3_DATA_BRP_MIN, > + .brp_max = ESD_USB3_DATA_BRP_MAX, > + .brp_inc = ESD_USB3_DATA_BRP_INC, > +}; > + > static int esd_usb2_set_bittiming(struct net_device *netdev) > { > - struct esd_usb2_net_priv *priv = netdev_priv(netdev); > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > struct can_bittiming *bt = &priv->can.bittiming; > - struct esd_usb2_msg *msg; > + struct esd_usb_msg *msg; > int err; > u32 canbtr; > int sjw_shift; > @@ -913,19 +1108,15 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) > > canbtr |= (bt->brp - 1) & (ESD_USB2_BRP_MAX - 1); > > - if (le16_to_cpu(priv->usb2->udev->descriptor.idProduct) == > - USB_CANUSBM_PRODUCT_ID) > + if (le16_to_cpu(priv->usb->udev->descriptor.idProduct) == USB_CANUSBM_PRODUCT_ID) > sjw_shift = ESD_USBM_SJW_SHIFT; > else > sjw_shift = ESD_USB2_SJW_SHIFT; > > - canbtr |= ((bt->sjw - 1) & (ESD_USB2_SJW_MAX - 1)) > - << sjw_shift; > - canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1) > - & (ESD_USB2_TSEG1_MAX - 1)) > + canbtr |= ((bt->sjw - 1) & (ESD_USB2_SJW_MAX - 1)) << sjw_shift; > + canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1) & (ESD_USB2_TSEG1_MAX - 1)) > << ESD_USB2_TSEG1_SHIFT; > - canbtr |= ((bt->phase_seg2 - 1) & (ESD_USB2_TSEG2_MAX - 1)) > - << ESD_USB2_TSEG2_SHIFT; > + canbtr |= ((bt->phase_seg2 - 1) & (ESD_USB2_TSEG2_MAX - 1)) << ESD_USB2_TSEG2_SHIFT; > if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) > canbtr |= ESD_USB2_3_SAMPLES; > > @@ -937,20 +1128,97 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) > msg->msg.hdr.cmd = CMD_SETBAUD; > msg->msg.setbaud.net = priv->index; > msg->msg.setbaud.rsvd = 0; > - msg->msg.setbaud.baud = cpu_to_le32(canbtr); > + msg->msg.setbaud.u.baud = cpu_to_le32(canbtr); > > netdev_info(netdev, "setting BTR=%#x\n", canbtr); > > - err = esd_usb2_send_msg(priv->usb2, msg); > + err = esd_usb_send_msg(priv->usb, msg); > + > + kfree(msg); > + return err; > +} > + > +static int esd_usb3_set_bittiming(struct net_device *netdev) > +{ > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > + struct can_bittiming *bt = &priv->can.bittiming; > + struct can_bittiming *d_bt = &priv->can.data_bittiming; > + struct esd_usb_msg *msg; > + int err; > + u16 mode; > + u16 flags = 0; > + u16 brp, tseg1, tseg2, sjw; > + u16 d_brp, d_tseg1, d_tseg2, d_sjw; > + > + msg = kmalloc(sizeof(*msg), GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + /* Canonical is the most reasonable mode for SocketCAN on CAN-USB/3 ... */ > + mode = ESD_BAUDRATE_MODE_BTR_CANONICAL; > + > + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) > + flags |= ESD_BAUDRATE_FLAG_LOM; > + > + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) > + flags |= ESD_BAUDRATE_FLAG_TRS; > + > + brp = bt->brp & (ESD_USB3_BRP_MAX - 1); > + sjw = bt->sjw & (ESD_USB3_SJW_MAX - 1); > + tseg1 = (bt->prop_seg + bt->phase_seg1) & (ESD_USB3_TSEG1_MAX - 1); > + tseg2 = bt->phase_seg2 & (ESD_USB3_TSEG2_MAX - 1); > + > + msg->msg.setbaud.u.baud_x.arb.brp = cpu_to_le16(brp); > + msg->msg.setbaud.u.baud_x.arb.sjw = cpu_to_le16(sjw); > + msg->msg.setbaud.u.baud_x.arb.tseg1 = cpu_to_le16(tseg1); > + msg->msg.setbaud.u.baud_x.arb.tseg2 = cpu_to_le16(tseg2); > + > + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { > + d_brp = d_bt->brp & (ESD_USB3_DATA_BRP_MAX - 1); > + d_sjw = d_bt->sjw & (ESD_USB3_DATA_SJW_MAX - 1); > + d_tseg1 = (d_bt->prop_seg + d_bt->phase_seg1) & (ESD_USB3_DATA_TSEG1_MAX - 1); > + d_tseg2 = d_bt->phase_seg2 & (ESD_USB3_DATA_TSEG2_MAX - 1); > + flags |= ESD_BAUDRATE_FLAG_FD; > + } else { > + d_brp = 0; > + d_sjw = 0; > + d_tseg1 = 0; > + d_tseg2 = 0; > + } > + > + msg->msg.setbaud.u.baud_x.data.brp = cpu_to_le16(d_brp); > + msg->msg.setbaud.u.baud_x.data.sjw = cpu_to_le16(d_sjw); > + msg->msg.setbaud.u.baud_x.data.tseg1 = cpu_to_le16(d_tseg1); > + msg->msg.setbaud.u.baud_x.data.tseg2 = cpu_to_le16(d_tseg2); > + msg->msg.setbaud.u.baud_x.mode = cpu_to_le16(mode); > + msg->msg.setbaud.u.baud_x.flags = cpu_to_le16(flags); > + msg->msg.setbaud.u.baud_x.tdc.tdc_mode = ESD_TDC_MODE_AUTO; > + msg->msg.setbaud.u.baud_x.tdc.ssp_offset = 0; > + msg->msg.setbaud.u.baud_x.tdc.ssp_shift = 0; > + msg->msg.setbaud.u.baud_x.tdc.tdc_filter = 0; > + > + msg->msg.hdr.len = 7; > + msg->msg.hdr.cmd = CMD_SETBAUD; > + > + msg->msg.setbaud.net = priv->index; > + msg->msg.setbaud.rsvd = 0; > + > + netdev_info(netdev, > + "ctrlmode:{ is:%#x, spprted:%#x }, esd-net:%u, esd-mode:%#x, esd-flg:%#x, arb:{ brp:%u, ts1:%u, ts2:%u, sjw:%u }, data:{ dbrp:%u, dts1:%u, dts2:%u dsjw:%u }\n", > + priv->can.ctrlmode, priv->can.ctrlmode_supported, > + priv->index, mode, flags, > + brp, tseg1, tseg2, sjw, > + d_brp, d_tseg1, d_tseg2, d_sjw); Please remove it make it a netdev_debug() > + > + err = esd_usb_send_msg(priv->usb, msg); > > kfree(msg); > return err; > } > > -static int esd_usb2_get_berr_counter(const struct net_device *netdev, > - struct can_berr_counter *bec) > +static int esd_usb_get_berr_counter(const struct net_device *netdev, struct can_berr_counter *bec) > { > - struct esd_usb2_net_priv *priv = netdev_priv(netdev); > + struct esd_usb_net_priv *priv = netdev_priv(netdev); > > bec->txerr = priv->bec.txerr; > bec->rxerr = priv->bec.rxerr; > @@ -958,7 +1226,7 @@ static int esd_usb2_get_berr_counter(const struct net_device *netdev, > return 0; > } > > -static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode) > +static int esd_usb_set_mode(struct net_device *netdev, enum can_mode mode) > { > switch (mode) { > case CAN_MODE_START: > @@ -972,11 +1240,11 @@ static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode) > return 0; > } > > -static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) > +static int esd_usb_probe_one_net(struct usb_interface *intf, int index) > { > - struct esd_usb2 *dev = usb_get_intfdata(intf); > + struct esd_usb *dev = usb_get_intfdata(intf); > struct net_device *netdev; > - struct esd_usb2_net_priv *priv; > + struct esd_usb_net_priv *priv; > int err = 0; > int i; > > @@ -995,30 +1263,45 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) > for (i = 0; i < MAX_TX_URBS; i++) > priv->tx_contexts[i].echo_index = MAX_TX_URBS; > > - priv->usb2 = dev; > + priv->usb = dev; > priv->netdev = netdev; > priv->index = index; > > priv->can.state = CAN_STATE_STOPPED; > - priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | > - CAN_CTRLMODE_CC_LEN8_DLC; > + priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_CC_LEN8_DLC; > + > + switch (le16_to_cpu(dev->udev->descriptor.idProduct)) { > + case USB_CANUSB3_PRODUCT_ID: > + priv->can.clock.freq = ESD_USB3_CAN_CLOCK; > + priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; > + priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; > + priv->can.bittiming_const = &esd_usb3_bittiming_const; > + priv->can.data_bittiming_const = &esd_usb3_data_bittiming_const; > + priv->can.do_set_bittiming = esd_usb3_set_bittiming; > + priv->can.do_set_data_bittiming = esd_usb3_set_bittiming; > + break; > > - if (le16_to_cpu(dev->udev->descriptor.idProduct) == > - USB_CANUSBM_PRODUCT_ID) > + case USB_CANUSBM_PRODUCT_ID: > priv->can.clock.freq = ESD_USBM_CAN_CLOCK; > - else { > + priv->can.bittiming_const = &esd_usb2_bittiming_const; > + priv->can.do_set_bittiming = esd_usb2_set_bittiming; > + break; > + > + case USB_CANUSB2_PRODUCT_ID: > + default: > priv->can.clock.freq = ESD_USB2_CAN_CLOCK; > priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; > + priv->can.bittiming_const = &esd_usb2_bittiming_const; > + priv->can.do_set_bittiming = esd_usb2_set_bittiming; > + break; > } > > - priv->can.bittiming_const = &esd_usb2_bittiming_const; > - priv->can.do_set_bittiming = esd_usb2_set_bittiming; > - priv->can.do_set_mode = esd_usb2_set_mode; > - priv->can.do_get_berr_counter = esd_usb2_get_berr_counter; > + priv->can.do_set_mode = esd_usb_set_mode; > + priv->can.do_get_berr_counter = esd_usb_get_berr_counter; > > netdev->flags |= IFF_ECHO; /* we support local echo */ > > - netdev->netdev_ops = &esd_usb2_netdev_ops; > + netdev->netdev_ops = &esd_usb_netdev_ops; > > SET_NETDEV_DEV(netdev, &intf->dev); > netdev->dev_id = index; > @@ -1044,11 +1327,10 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) > * check version information and number of available > * CAN interfaces > */ > -static int esd_usb2_probe(struct usb_interface *intf, > - const struct usb_device_id *id) > +static int esd_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) > { > - struct esd_usb2 *dev; > - struct esd_usb2_msg *msg; > + struct esd_usb *dev; > + struct esd_usb_msg *msg; > int i, err; > > dev = kzalloc(sizeof(*dev), GFP_KERNEL); > @@ -1076,13 +1358,13 @@ static int esd_usb2_probe(struct usb_interface *intf, > msg->msg.version.flags = 0; > msg->msg.version.drv_version = 0; > > - err = esd_usb2_send_msg(dev, msg); > + err = esd_usb_send_msg(dev, msg); > if (err < 0) { > dev_err(&intf->dev, "sending version message failed\n"); > goto free_msg; > } > > - err = esd_usb2_wait_msg(dev, msg); > + err = esd_usb_wait_msg(dev, msg); > if (err < 0) { > dev_err(&intf->dev, "no version message answer\n"); > goto free_msg; > @@ -1091,21 +1373,26 @@ static int esd_usb2_probe(struct usb_interface *intf, > dev->net_count = (int)msg->msg.version_reply.nets; > dev->version = le32_to_cpu(msg->msg.version_reply.version); > > + dev_info(&intf->dev, "version:{ hw:%d.%d.%d fw:%d.%d.%d }\n", > + (dev->version >> 28) & 0xf, > + (dev->version >> 24) & 0xf, > + (dev->version >> 16) & 0xff, > + (dev->version >> 12) & 0xf, > + (dev->version >> 8) & 0xf, > + (dev->version) & 0xff); > + > if (device_create_file(&intf->dev, &dev_attr_firmware)) > - dev_err(&intf->dev, > - "Couldn't create device file for firmware\n"); > + dev_err(&intf->dev, "Couldn't create device file for firmware\n"); > > if (device_create_file(&intf->dev, &dev_attr_hardware)) > - dev_err(&intf->dev, > - "Couldn't create device file for hardware\n"); > + dev_err(&intf->dev, "Couldn't create device file for hardware\n"); > > if (device_create_file(&intf->dev, &dev_attr_nets)) > - dev_err(&intf->dev, > - "Couldn't create device file for nets\n"); > + dev_err(&intf->dev, "Couldn't create device file for nets\n"); > > /* do per device probing */ > for (i = 0; i < dev->net_count; i++) > - esd_usb2_probe_one_net(intf, i); > + esd_usb_probe_one_net(intf, i); > > free_msg: > kfree(msg); > @@ -1118,9 +1405,9 @@ static int esd_usb2_probe(struct usb_interface *intf, > /* > * called by the usb core when the device is removed from the system > */ > -static void esd_usb2_disconnect(struct usb_interface *intf) > +static void esd_usb_disconnect(struct usb_interface *intf) > { > - struct esd_usb2 *dev = usb_get_intfdata(intf); > + struct esd_usb *dev = usb_get_intfdata(intf); > struct net_device *netdev; > int i; > > @@ -1144,11 +1431,11 @@ static void esd_usb2_disconnect(struct usb_interface *intf) > } > > /* usb specific object needed to register this driver with the usb subsystem */ > -static struct usb_driver esd_usb2_driver = { > - .name = "esd_usb2", > - .probe = esd_usb2_probe, > - .disconnect = esd_usb2_disconnect, > - .id_table = esd_usb2_table, > +static struct usb_driver esd_usb_driver = { > + .name = "esd_usb", > + .probe = esd_usb_probe, > + .disconnect = esd_usb_disconnect, > + .id_table = esd_usb_table, > }; > > -module_usb_driver(esd_usb2_driver); > +module_usb_driver(esd_usb_driver); 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:
signature.asc
Description: PGP signature