[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220620202603.2069841-2-frank.jungclaus@esd.eu>
Date: Mon, 20 Jun 2022 22:26:03 +0200
From: Frank Jungclaus <frank.jungclaus@....eu>
To: linux-can@...r.kernel.org, Marc Kleine-Budde <mkl@...gutronix.de>,
Wolfgang Grandegger <wg@...ndegger.com>,
Vincent Mailhol <mailhol.vincent@...adoo.fr>
Cc: Stefan Mätje <stefan.maetje@....eu>,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
Frank Jungclaus <frank.jungclaus@....eu>
Subject: [PATCH 1/1] can/esd_usb2: Added support for esd CAN-USB/3
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@....eu>, esd gmbh
+ * Copyright (C) 2010- Matthias Fuchs , esd gmbh
+ * Copyright (C) 2022- Frank Jungclaus <frank.jungclaus@....eu>, esd gmbh
*/
+
#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@....eu>");
-MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces");
+MODULE_AUTHOR("Frank Jungclaus <frank.jungclaus@....eu>");
+MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2, CAN-USB/3 and CAN-USB/Micro interfaces");
MODULE_LICENSE("GPL v2");
-/* 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
+
/* 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 {
+ __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;
};
/* 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)
+ {
+ 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];
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 ...
+ */
+ 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);
+
+ 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);
--
2.25.1
Powered by blists - more mailing lists