xref: /openbmc/linux/drivers/net/can/usb/esd_usb.c (revision 34d6f206a88c2651d216bd3487ac956a40b2ba8e)
15e910bdeSFrank Jungclaus // SPDX-License-Identifier: GPL-2.0-only
25e910bdeSFrank Jungclaus /*
380662d94SFrank Jungclaus  * CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro
45e910bdeSFrank Jungclaus  *
5ce87c0f1SFrank Jungclaus  * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <socketcan@esd.eu>
6*9ecd9d7aSStefan Mätje  * Copyright (C) 2022-2024 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu>
75e910bdeSFrank Jungclaus  */
85e910bdeSFrank Jungclaus 
95e910bdeSFrank Jungclaus #include <linux/can.h>
105e910bdeSFrank Jungclaus #include <linux/can/dev.h>
115e910bdeSFrank Jungclaus #include <linux/can/error.h>
121ad549cfSFrank Jungclaus #include <linux/ethtool.h>
131ad549cfSFrank Jungclaus #include <linux/module.h>
141ad549cfSFrank Jungclaus #include <linux/netdevice.h>
151ad549cfSFrank Jungclaus #include <linux/signal.h>
161ad549cfSFrank Jungclaus #include <linux/slab.h>
171ad549cfSFrank Jungclaus #include <linux/units.h>
181ad549cfSFrank Jungclaus #include <linux/usb.h>
195e910bdeSFrank Jungclaus 
20ce87c0f1SFrank Jungclaus MODULE_AUTHOR("Matthias Fuchs <socketcan@esd.eu>");
21ce87c0f1SFrank Jungclaus MODULE_AUTHOR("Frank Jungclaus <frank.jungclaus@esd.eu>");
2280662d94SFrank Jungclaus MODULE_DESCRIPTION("CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro interfaces");
235e910bdeSFrank Jungclaus MODULE_LICENSE("GPL v2");
245e910bdeSFrank Jungclaus 
254d54977fSFrank Jungclaus /* USB vendor and product ID */
269dc3a695SFrank Jungclaus #define ESD_USB_ESDGMBH_VENDOR_ID	0x0ab4
279dc3a695SFrank Jungclaus #define ESD_USB_CANUSB2_PRODUCT_ID	0x0010
289dc3a695SFrank Jungclaus #define ESD_USB_CANUSBM_PRODUCT_ID	0x0011
2980662d94SFrank Jungclaus #define ESD_USB_CANUSB3_PRODUCT_ID	0x0014
305e910bdeSFrank Jungclaus 
314d54977fSFrank Jungclaus /* CAN controller clock frequencies */
329dc3a695SFrank Jungclaus #define ESD_USB_2_CAN_CLOCK	(60 * MEGA) /* Hz */
339dc3a695SFrank Jungclaus #define ESD_USB_M_CAN_CLOCK	(36 * MEGA) /* Hz */
3480662d94SFrank Jungclaus #define ESD_USB_3_CAN_CLOCK	(80 * MEGA) /* Hz */
355e910bdeSFrank Jungclaus 
364d54977fSFrank Jungclaus /* Maximum number of CAN nets */
374d54977fSFrank Jungclaus #define ESD_USB_MAX_NETS	2
384d54977fSFrank Jungclaus 
394d54977fSFrank Jungclaus /* USB commands */
409dc3a695SFrank Jungclaus #define ESD_USB_CMD_VERSION		1 /* also used for VERSION_REPLY */
419dc3a695SFrank Jungclaus #define ESD_USB_CMD_CAN_RX		2 /* device to host only */
429dc3a695SFrank Jungclaus #define ESD_USB_CMD_CAN_TX		3 /* also used for TX_DONE */
439dc3a695SFrank Jungclaus #define ESD_USB_CMD_SETBAUD		4 /* also used for SETBAUD_REPLY */
449dc3a695SFrank Jungclaus #define ESD_USB_CMD_TS			5 /* also used for TS_REPLY */
459dc3a695SFrank Jungclaus #define ESD_USB_CMD_IDADD		6 /* also used for IDADD_REPLY */
465e910bdeSFrank Jungclaus 
475e910bdeSFrank Jungclaus /* esd CAN message flags - dlc field */
488a99f2adSFrank Jungclaus #define ESD_USB_RTR	BIT(4)
4980662d94SFrank Jungclaus #define ESD_USB_NO_BRS	BIT(4)
5080662d94SFrank Jungclaus #define ESD_USB_ESI	BIT(5)
5180662d94SFrank Jungclaus #define ESD_USB_FD	BIT(7)
525e910bdeSFrank Jungclaus 
535e910bdeSFrank Jungclaus /* esd CAN message flags - id field */
549dc3a695SFrank Jungclaus #define ESD_USB_EXTID	BIT(29)
559dc3a695SFrank Jungclaus #define ESD_USB_EVENT	BIT(30)
569dc3a695SFrank Jungclaus #define ESD_USB_IDMASK	GENMASK(28, 0)
575e910bdeSFrank Jungclaus 
584d54977fSFrank Jungclaus /* esd CAN event ids */
598a99f2adSFrank Jungclaus #define ESD_USB_EV_CAN_ERROR_EXT	2 /* CAN controller specific diagnostic data */
605e910bdeSFrank Jungclaus 
615e910bdeSFrank Jungclaus /* baudrate message flags */
621ad549cfSFrank Jungclaus #define ESD_USB_LOM	BIT(30) /* Listen Only Mode */
631ad549cfSFrank Jungclaus #define ESD_USB_UBR	BIT(31) /* User Bit Rate (controller BTR) in bits 0..27 */
641ad549cfSFrank Jungclaus #define ESD_USB_NO_BAUDRATE	GENMASK(30, 0) /* bit rate unconfigured */
654d54977fSFrank Jungclaus 
669dc3a695SFrank Jungclaus /* bit timing esd CAN-USB */
679dc3a695SFrank Jungclaus #define ESD_USB_2_TSEG1_SHIFT	16
689dc3a695SFrank Jungclaus #define ESD_USB_2_TSEG2_SHIFT	20
699dc3a695SFrank Jungclaus #define ESD_USB_2_SJW_SHIFT	14
709dc3a695SFrank Jungclaus #define ESD_USB_M_SJW_SHIFT	24
719dc3a695SFrank Jungclaus #define ESD_USB_TRIPLE_SAMPLES	BIT(23)
725e910bdeSFrank Jungclaus 
7380662d94SFrank Jungclaus /* Transmitter Delay Compensation */
7480662d94SFrank Jungclaus #define ESD_USB_3_TDC_MODE_AUTO	0
7580662d94SFrank Jungclaus 
765e910bdeSFrank Jungclaus /* esd IDADD message */
7733665fdbSFrank Jungclaus #define ESD_USB_ID_ENABLE	BIT(7)
789dc3a695SFrank Jungclaus #define ESD_USB_MAX_ID_SEGMENT	64
795e910bdeSFrank Jungclaus 
804d54977fSFrank Jungclaus /* SJA1000 ECC register (emulated by usb firmware) */
8133665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_SEG		GENMASK(4, 0)
8233665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_DIR		BIT(5)
8333665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_ERR		BIT(2, 1)
849dc3a695SFrank Jungclaus #define ESD_USB_SJA1000_ECC_BIT		0x00
8533665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_FORM	BIT(6)
8633665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_STUFF	BIT(7)
8733665fdbSFrank Jungclaus #define ESD_USB_SJA1000_ECC_MASK	GENMASK(7, 6)
885e910bdeSFrank Jungclaus 
895e910bdeSFrank Jungclaus /* esd bus state event codes */
9033665fdbSFrank Jungclaus #define ESD_USB_BUSSTATE_MASK	GENMASK(7, 6)
9133665fdbSFrank Jungclaus #define ESD_USB_BUSSTATE_WARN	BIT(6)
9233665fdbSFrank Jungclaus #define ESD_USB_BUSSTATE_ERRPASSIVE	BIT(7)
9333665fdbSFrank Jungclaus #define ESD_USB_BUSSTATE_BUSOFF	GENMASK(7, 6)
945e910bdeSFrank Jungclaus 
959dc3a695SFrank Jungclaus #define ESD_USB_RX_BUFFER_SIZE		1024
969dc3a695SFrank Jungclaus #define ESD_USB_MAX_RX_URBS		4
979dc3a695SFrank Jungclaus #define ESD_USB_MAX_TX_URBS		16 /* must be power of 2 */
985e910bdeSFrank Jungclaus 
9980662d94SFrank Jungclaus /* Modes for CAN-USB/3, to be used for esd_usb_3_set_baudrate_msg_x.mode */
10080662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_DISABLE		0 /* remove from bus */
10180662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_INDEX		1 /* ESD (CiA) bit rate idx */
10280662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_BTR_CTRL	2 /* BTR values (controller)*/
10380662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_BTR_CANONICAL	3 /* BTR values (canonical) */
10480662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_NUM		4 /* numerical bit rate */
10580662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_MODE_AUTOBAUD	5 /* autobaud */
10680662d94SFrank Jungclaus 
10780662d94SFrank Jungclaus /* Flags for CAN-USB/3, to be used for esd_usb_3_set_baudrate_msg_x.flags */
10880662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_FLAG_FD	BIT(0) /* enable CAN FD mode */
10980662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_FLAG_LOM	BIT(1) /* enable listen only mode */
11080662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_FLAG_STM	BIT(2) /* enable self test mode */
11180662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_FLAG_TRS	BIT(3) /* enable triple sampling */
11280662d94SFrank Jungclaus #define ESD_USB_3_BAUDRATE_FLAG_TXP	BIT(4) /* enable transmit pause */
11380662d94SFrank Jungclaus 
1148ef426e1SFrank Jungclaus struct esd_usb_header_msg {
115299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1165e910bdeSFrank Jungclaus 	u8 cmd;
1175e910bdeSFrank Jungclaus 	u8 rsvd[2];
1185e910bdeSFrank Jungclaus };
1195e910bdeSFrank Jungclaus 
1208ef426e1SFrank Jungclaus struct esd_usb_version_msg {
121299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1225e910bdeSFrank Jungclaus 	u8 cmd;
1235e910bdeSFrank Jungclaus 	u8 rsvd;
1245e910bdeSFrank Jungclaus 	u8 flags;
1255e910bdeSFrank Jungclaus 	__le32 drv_version;
1265e910bdeSFrank Jungclaus };
1275e910bdeSFrank Jungclaus 
1288ef426e1SFrank Jungclaus struct esd_usb_version_reply_msg {
129299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1305e910bdeSFrank Jungclaus 	u8 cmd;
1315e910bdeSFrank Jungclaus 	u8 nets;
1325e910bdeSFrank Jungclaus 	u8 features;
1335e910bdeSFrank Jungclaus 	__le32 version;
1345e910bdeSFrank Jungclaus 	u8 name[16];
1355e910bdeSFrank Jungclaus 	__le32 rsvd;
1365e910bdeSFrank Jungclaus 	__le32 ts;
1375e910bdeSFrank Jungclaus };
1385e910bdeSFrank Jungclaus 
1398ef426e1SFrank Jungclaus struct esd_usb_rx_msg {
140299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1415e910bdeSFrank Jungclaus 	u8 cmd;
1425e910bdeSFrank Jungclaus 	u8 net;
1435e910bdeSFrank Jungclaus 	u8 dlc;
1445e910bdeSFrank Jungclaus 	__le32 ts;
1455e910bdeSFrank Jungclaus 	__le32 id; /* upper 3 bits contain flags */
14607c3f922SFrank Jungclaus 	union {
1471ad549cfSFrank Jungclaus 		u8 data[CAN_MAX_DLEN];
14880662d94SFrank Jungclaus 		u8 data_fd[CANFD_MAX_DLEN];
14907c3f922SFrank Jungclaus 		struct {
15007c3f922SFrank Jungclaus 			u8 status; /* CAN Controller Status */
15107c3f922SFrank Jungclaus 			u8 ecc;    /* Error Capture Register */
15207c3f922SFrank Jungclaus 			u8 rec;    /* RX Error Counter */
15307c3f922SFrank Jungclaus 			u8 tec;    /* TX Error Counter */
15407c3f922SFrank Jungclaus 		} ev_can_err_ext;  /* For ESD_EV_CAN_ERROR_EXT */
15507c3f922SFrank Jungclaus 	};
1565e910bdeSFrank Jungclaus };
1575e910bdeSFrank Jungclaus 
1588ef426e1SFrank Jungclaus struct esd_usb_tx_msg {
159299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1605e910bdeSFrank Jungclaus 	u8 cmd;
1615e910bdeSFrank Jungclaus 	u8 net;
1625e910bdeSFrank Jungclaus 	u8 dlc;
1635e910bdeSFrank Jungclaus 	u32 hnd;	/* opaque handle, not used by device */
1645e910bdeSFrank Jungclaus 	__le32 id; /* upper 3 bits contain flags */
16580662d94SFrank Jungclaus 	union {
1661ad549cfSFrank Jungclaus 		u8 data[CAN_MAX_DLEN];
16780662d94SFrank Jungclaus 		u8 data_fd[CANFD_MAX_DLEN];
16880662d94SFrank Jungclaus 	};
1695e910bdeSFrank Jungclaus };
1705e910bdeSFrank Jungclaus 
1718ef426e1SFrank Jungclaus struct esd_usb_tx_done_msg {
172299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1735e910bdeSFrank Jungclaus 	u8 cmd;
1745e910bdeSFrank Jungclaus 	u8 net;
1755e910bdeSFrank Jungclaus 	u8 status;
1765e910bdeSFrank Jungclaus 	u32 hnd;	/* opaque handle, not used by device */
1775e910bdeSFrank Jungclaus 	__le32 ts;
1785e910bdeSFrank Jungclaus };
1795e910bdeSFrank Jungclaus 
1808ef426e1SFrank Jungclaus struct esd_usb_id_filter_msg {
181299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1825e910bdeSFrank Jungclaus 	u8 cmd;
1835e910bdeSFrank Jungclaus 	u8 net;
1845e910bdeSFrank Jungclaus 	u8 option;
185299a5576SFrank Jungclaus 	__le32 mask[ESD_USB_MAX_ID_SEGMENT + 1]; /* +1 for 29bit extended IDs */
1865e910bdeSFrank Jungclaus };
1875e910bdeSFrank Jungclaus 
1888ef426e1SFrank Jungclaus struct esd_usb_set_baudrate_msg {
189299a5576SFrank Jungclaus 	u8 len; /* total message length in 32bit words */
1905e910bdeSFrank Jungclaus 	u8 cmd;
1915e910bdeSFrank Jungclaus 	u8 net;
1925e910bdeSFrank Jungclaus 	u8 rsvd;
1935e910bdeSFrank Jungclaus 	__le32 baud;
1945e910bdeSFrank Jungclaus };
1955e910bdeSFrank Jungclaus 
19680662d94SFrank Jungclaus /* CAN-USB/3 baudrate configuration, used for nominal as well as for data bit rate */
19780662d94SFrank Jungclaus struct esd_usb_3_baudrate_cfg {
19880662d94SFrank Jungclaus 	__le16 brp;	/* bit rate pre-scaler */
19980662d94SFrank Jungclaus 	__le16 tseg1;	/* time segment before sample point */
20080662d94SFrank Jungclaus 	__le16 tseg2;	/* time segment after sample point */
20180662d94SFrank Jungclaus 	__le16 sjw;	/* synchronization jump Width */
20280662d94SFrank Jungclaus };
20380662d94SFrank Jungclaus 
20480662d94SFrank Jungclaus /* In principle, the esd CAN-USB/3 supports Transmitter Delay Compensation (TDC),
20580662d94SFrank Jungclaus  * but currently only the automatic TDC mode is supported by this driver.
20680662d94SFrank Jungclaus  * An implementation for manual TDC configuration will follow.
20780662d94SFrank Jungclaus  *
20880662d94SFrank Jungclaus  * For information about struct esd_usb_3_tdc_cfg, see
20980662d94SFrank Jungclaus  * NTCAN Application Developers Manual, 6.2.25 NTCAN_TDC_CFG + related chapters
21080662d94SFrank Jungclaus  * https://esd.eu/fileadmin/esd/docs/manuals/NTCAN_Part1_Function_API_Manual_en_56.pdf
21180662d94SFrank Jungclaus  */
21280662d94SFrank Jungclaus struct esd_usb_3_tdc_cfg {
21380662d94SFrank Jungclaus 	u8 tdc_mode;	/* transmitter delay compensation mode  */
21480662d94SFrank Jungclaus 	u8 ssp_offset;	/* secondary sample point offset in mtq */
21580662d94SFrank Jungclaus 	s8 ssp_shift;	/* secondary sample point shift in mtq */
21680662d94SFrank Jungclaus 	u8 tdc_filter;	/* TDC filter in mtq */
21780662d94SFrank Jungclaus };
21880662d94SFrank Jungclaus 
21980662d94SFrank Jungclaus /* Extended version of the above set_baudrate_msg for a CAN-USB/3
22080662d94SFrank Jungclaus  * to define the CAN bit timing configuration of the CAN controller in
22180662d94SFrank Jungclaus  * CAN FD mode as well as in Classical CAN mode.
22280662d94SFrank Jungclaus  *
22380662d94SFrank Jungclaus  * The payload of this command is a NTCAN_BAUDRATE_X structure according to
22480662d94SFrank Jungclaus  * esd electronics gmbh, NTCAN Application Developers Manual, 6.2.15 NTCAN_BAUDRATE_X
22580662d94SFrank Jungclaus  * https://esd.eu/fileadmin/esd/docs/manuals/NTCAN_Part1_Function_API_Manual_en_56.pdf
22680662d94SFrank Jungclaus  */
22780662d94SFrank Jungclaus struct esd_usb_3_set_baudrate_msg_x {
22880662d94SFrank Jungclaus 	u8 len;	/* total message length in 32bit words */
22980662d94SFrank Jungclaus 	u8 cmd;
23080662d94SFrank Jungclaus 	u8 net;
23180662d94SFrank Jungclaus 	u8 rsvd;	/*reserved */
23280662d94SFrank Jungclaus 	/* Payload ... */
23380662d94SFrank Jungclaus 	__le16 mode;	/* mode word, see ESD_USB_3_BAUDRATE_MODE_xxx */
23480662d94SFrank Jungclaus 	__le16 flags;	/* control flags, see ESD_USB_3_BAUDRATE_FLAG_xxx */
23580662d94SFrank Jungclaus 	struct esd_usb_3_tdc_cfg tdc;	/* TDC configuration */
23680662d94SFrank Jungclaus 	struct esd_usb_3_baudrate_cfg nom;	/* nominal bit rate */
23780662d94SFrank Jungclaus 	struct esd_usb_3_baudrate_cfg data;	/* data bit rate */
23880662d94SFrank Jungclaus };
23980662d94SFrank Jungclaus 
2405e910bdeSFrank Jungclaus /* Main message type used between library and application */
241a57915aeSFrank Jungclaus union __packed esd_usb_msg {
2428ef426e1SFrank Jungclaus 	struct esd_usb_header_msg hdr;
2438ef426e1SFrank Jungclaus 	struct esd_usb_version_msg version;
2448ef426e1SFrank Jungclaus 	struct esd_usb_version_reply_msg version_reply;
2458ef426e1SFrank Jungclaus 	struct esd_usb_rx_msg rx;
2468ef426e1SFrank Jungclaus 	struct esd_usb_tx_msg tx;
2478ef426e1SFrank Jungclaus 	struct esd_usb_tx_done_msg txdone;
2488ef426e1SFrank Jungclaus 	struct esd_usb_set_baudrate_msg setbaud;
24980662d94SFrank Jungclaus 	struct esd_usb_3_set_baudrate_msg_x setbaud_x;
2508ef426e1SFrank Jungclaus 	struct esd_usb_id_filter_msg filter;
2515e910bdeSFrank Jungclaus };
2525e910bdeSFrank Jungclaus 
2534d54977fSFrank Jungclaus static struct usb_device_id esd_usb_table[] = {
2549dc3a695SFrank Jungclaus 	{USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSB2_PRODUCT_ID)},
2559dc3a695SFrank Jungclaus 	{USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSBM_PRODUCT_ID)},
25680662d94SFrank Jungclaus 	{USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSB3_PRODUCT_ID)},
2575e910bdeSFrank Jungclaus 	{}
2585e910bdeSFrank Jungclaus };
2594d54977fSFrank Jungclaus MODULE_DEVICE_TABLE(usb, esd_usb_table);
2605e910bdeSFrank Jungclaus 
2614d54977fSFrank Jungclaus struct esd_usb_net_priv;
2625e910bdeSFrank Jungclaus 
2635e910bdeSFrank Jungclaus struct esd_tx_urb_context {
2644d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv;
2655e910bdeSFrank Jungclaus 	u32 echo_index;
2665e910bdeSFrank Jungclaus };
2675e910bdeSFrank Jungclaus 
2684d54977fSFrank Jungclaus struct esd_usb {
2695e910bdeSFrank Jungclaus 	struct usb_device *udev;
2704d54977fSFrank Jungclaus 	struct esd_usb_net_priv *nets[ESD_USB_MAX_NETS];
2715e910bdeSFrank Jungclaus 
2725e910bdeSFrank Jungclaus 	struct usb_anchor rx_submitted;
2735e910bdeSFrank Jungclaus 
2745e910bdeSFrank Jungclaus 	int net_count;
2755e910bdeSFrank Jungclaus 	u32 version;
2765e910bdeSFrank Jungclaus 	int rxinitdone;
2779dc3a695SFrank Jungclaus 	void *rxbuf[ESD_USB_MAX_RX_URBS];
2789dc3a695SFrank Jungclaus 	dma_addr_t rxbuf_dma[ESD_USB_MAX_RX_URBS];
2795e910bdeSFrank Jungclaus };
2805e910bdeSFrank Jungclaus 
2814d54977fSFrank Jungclaus struct esd_usb_net_priv {
2825e910bdeSFrank Jungclaus 	struct can_priv can; /* must be the first member */
2835e910bdeSFrank Jungclaus 
2845e910bdeSFrank Jungclaus 	atomic_t active_tx_jobs;
2855e910bdeSFrank Jungclaus 	struct usb_anchor tx_submitted;
2869dc3a695SFrank Jungclaus 	struct esd_tx_urb_context tx_contexts[ESD_USB_MAX_TX_URBS];
2875e910bdeSFrank Jungclaus 
2884d54977fSFrank Jungclaus 	struct esd_usb *usb;
2895e910bdeSFrank Jungclaus 	struct net_device *netdev;
2905e910bdeSFrank Jungclaus 	int index;
2915e910bdeSFrank Jungclaus 	u8 old_state;
2925e910bdeSFrank Jungclaus 	struct can_berr_counter bec;
2935e910bdeSFrank Jungclaus };
2945e910bdeSFrank Jungclaus 
esd_usb_rx_event(struct esd_usb_net_priv * priv,union esd_usb_msg * msg)2954d54977fSFrank Jungclaus static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
296a57915aeSFrank Jungclaus 			     union esd_usb_msg *msg)
2975e910bdeSFrank Jungclaus {
2985e910bdeSFrank Jungclaus 	struct net_device_stats *stats = &priv->netdev->stats;
2995e910bdeSFrank Jungclaus 	struct can_frame *cf;
3005e910bdeSFrank Jungclaus 	struct sk_buff *skb;
3019dc3a695SFrank Jungclaus 	u32 id = le32_to_cpu(msg->rx.id) & ESD_USB_IDMASK;
3025e910bdeSFrank Jungclaus 
3038a99f2adSFrank Jungclaus 	if (id == ESD_USB_EV_CAN_ERROR_EXT) {
304a57915aeSFrank Jungclaus 		u8 state = msg->rx.ev_can_err_ext.status;
305a57915aeSFrank Jungclaus 		u8 ecc = msg->rx.ev_can_err_ext.ecc;
306c42fc369SFrank Jungclaus 
307c42fc369SFrank Jungclaus 		priv->bec.rxerr = msg->rx.ev_can_err_ext.rec;
308c42fc369SFrank Jungclaus 		priv->bec.txerr = msg->rx.ev_can_err_ext.tec;
3095e910bdeSFrank Jungclaus 
310918ee491SFrank Jungclaus 		netdev_dbg(priv->netdev,
311918ee491SFrank Jungclaus 			   "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
312c42fc369SFrank Jungclaus 			   msg->rx.dlc, state, ecc,
313c42fc369SFrank Jungclaus 			   priv->bec.rxerr, priv->bec.txerr);
314c42fc369SFrank Jungclaus 
315c42fc369SFrank Jungclaus 		/* if berr-reporting is off, only pass through on state change ... */
316c42fc369SFrank Jungclaus 		if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) &&
317c42fc369SFrank Jungclaus 		    state == priv->old_state)
318c42fc369SFrank Jungclaus 			return;
319918ee491SFrank Jungclaus 
3205e910bdeSFrank Jungclaus 		skb = alloc_can_err_skb(priv->netdev, &cf);
321c42fc369SFrank Jungclaus 		if (!skb)
322c42fc369SFrank Jungclaus 			stats->rx_dropped++;
3235e910bdeSFrank Jungclaus 
3245e910bdeSFrank Jungclaus 		if (state != priv->old_state) {
3259684b000SFrank Jungclaus 			enum can_state tx_state, rx_state;
3269684b000SFrank Jungclaus 			enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
3279684b000SFrank Jungclaus 
3285e910bdeSFrank Jungclaus 			priv->old_state = state;
3295e910bdeSFrank Jungclaus 
3309dc3a695SFrank Jungclaus 			switch (state & ESD_USB_BUSSTATE_MASK) {
3319dc3a695SFrank Jungclaus 			case ESD_USB_BUSSTATE_BUSOFF:
3329684b000SFrank Jungclaus 				new_state = CAN_STATE_BUS_OFF;
3335e910bdeSFrank Jungclaus 				can_bus_off(priv->netdev);
3345e910bdeSFrank Jungclaus 				break;
3359dc3a695SFrank Jungclaus 			case ESD_USB_BUSSTATE_WARN:
3369684b000SFrank Jungclaus 				new_state = CAN_STATE_ERROR_WARNING;
3375e910bdeSFrank Jungclaus 				break;
3389dc3a695SFrank Jungclaus 			case ESD_USB_BUSSTATE_ERRPASSIVE:
3399684b000SFrank Jungclaus 				new_state = CAN_STATE_ERROR_PASSIVE;
3405e910bdeSFrank Jungclaus 				break;
3415e910bdeSFrank Jungclaus 			default:
3429684b000SFrank Jungclaus 				new_state = CAN_STATE_ERROR_ACTIVE;
343c42fc369SFrank Jungclaus 				priv->bec.txerr = 0;
344c42fc369SFrank Jungclaus 				priv->bec.rxerr = 0;
3455e910bdeSFrank Jungclaus 				break;
3465e910bdeSFrank Jungclaus 			}
3479684b000SFrank Jungclaus 
3489684b000SFrank Jungclaus 			if (new_state != priv->can.state) {
349c42fc369SFrank Jungclaus 				tx_state = (priv->bec.txerr >= priv->bec.rxerr) ? new_state : 0;
350c42fc369SFrank Jungclaus 				rx_state = (priv->bec.txerr <= priv->bec.rxerr) ? new_state : 0;
3519684b000SFrank Jungclaus 				can_change_state(priv->netdev, cf,
3529684b000SFrank Jungclaus 						 tx_state, rx_state);
3539684b000SFrank Jungclaus 			}
3549684b000SFrank Jungclaus 		} else if (skb) {
3555e910bdeSFrank Jungclaus 			priv->can.can_stats.bus_error++;
3565e910bdeSFrank Jungclaus 			stats->rx_errors++;
3575e910bdeSFrank Jungclaus 
3589684b000SFrank Jungclaus 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
3595e910bdeSFrank Jungclaus 
3609dc3a695SFrank Jungclaus 			switch (ecc & ESD_USB_SJA1000_ECC_MASK) {
3619dc3a695SFrank Jungclaus 			case ESD_USB_SJA1000_ECC_BIT:
3625e910bdeSFrank Jungclaus 				cf->data[2] |= CAN_ERR_PROT_BIT;
3635e910bdeSFrank Jungclaus 				break;
3649dc3a695SFrank Jungclaus 			case ESD_USB_SJA1000_ECC_FORM:
3655e910bdeSFrank Jungclaus 				cf->data[2] |= CAN_ERR_PROT_FORM;
3665e910bdeSFrank Jungclaus 				break;
3679dc3a695SFrank Jungclaus 			case ESD_USB_SJA1000_ECC_STUFF:
3685e910bdeSFrank Jungclaus 				cf->data[2] |= CAN_ERR_PROT_STUFF;
3695e910bdeSFrank Jungclaus 				break;
3705e910bdeSFrank Jungclaus 			default:
3715e910bdeSFrank Jungclaus 				break;
3725e910bdeSFrank Jungclaus 			}
3735e910bdeSFrank Jungclaus 
3745e910bdeSFrank Jungclaus 			/* Error occurred during transmission? */
3759dc3a695SFrank Jungclaus 			if (!(ecc & ESD_USB_SJA1000_ECC_DIR))
3765e910bdeSFrank Jungclaus 				cf->data[2] |= CAN_ERR_PROT_TX;
3775e910bdeSFrank Jungclaus 
378118469f8SFrank Jungclaus 			/* Bit stream position in CAN frame as the error was detected */
3799dc3a695SFrank Jungclaus 			cf->data[3] = ecc & ESD_USB_SJA1000_ECC_SEG;
3805e910bdeSFrank Jungclaus 		}
3815e910bdeSFrank Jungclaus 
3829684b000SFrank Jungclaus 		if (skb) {
3839684b000SFrank Jungclaus 			cf->can_id |= CAN_ERR_CNT;
384c42fc369SFrank Jungclaus 			cf->data[6] = priv->bec.txerr;
385c42fc369SFrank Jungclaus 			cf->data[7] = priv->bec.rxerr;
3869684b000SFrank Jungclaus 
3875e910bdeSFrank Jungclaus 			netif_rx(skb);
3889684b000SFrank Jungclaus 		}
3895e910bdeSFrank Jungclaus 	}
3905e910bdeSFrank Jungclaus }
3915e910bdeSFrank Jungclaus 
esd_usb_rx_can_msg(struct esd_usb_net_priv * priv,union esd_usb_msg * msg)3924d54977fSFrank Jungclaus static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv,
393a57915aeSFrank Jungclaus 			       union esd_usb_msg *msg)
3945e910bdeSFrank Jungclaus {
3955e910bdeSFrank Jungclaus 	struct net_device_stats *stats = &priv->netdev->stats;
3965e910bdeSFrank Jungclaus 	struct can_frame *cf;
39780662d94SFrank Jungclaus 	struct canfd_frame *cfd;
3985e910bdeSFrank Jungclaus 	struct sk_buff *skb;
3995e910bdeSFrank Jungclaus 	u32 id;
40080662d94SFrank Jungclaus 	u8 len;
4015e910bdeSFrank Jungclaus 
4025e910bdeSFrank Jungclaus 	if (!netif_device_present(priv->netdev))
4035e910bdeSFrank Jungclaus 		return;
4045e910bdeSFrank Jungclaus 
405a57915aeSFrank Jungclaus 	id = le32_to_cpu(msg->rx.id);
4065e910bdeSFrank Jungclaus 
4079dc3a695SFrank Jungclaus 	if (id & ESD_USB_EVENT) {
4084d54977fSFrank Jungclaus 		esd_usb_rx_event(priv, msg);
4095e910bdeSFrank Jungclaus 	} else {
41080662d94SFrank Jungclaus 		if (msg->rx.dlc & ESD_USB_FD) {
41180662d94SFrank Jungclaus 			skb = alloc_canfd_skb(priv->netdev, &cfd);
41280662d94SFrank Jungclaus 		} else {
4135e910bdeSFrank Jungclaus 			skb = alloc_can_skb(priv->netdev, &cf);
41480662d94SFrank Jungclaus 			cfd = (struct canfd_frame *)cf;
41580662d94SFrank Jungclaus 		}
41680662d94SFrank Jungclaus 
4175e910bdeSFrank Jungclaus 		if (skb == NULL) {
4185e910bdeSFrank Jungclaus 			stats->rx_dropped++;
4195e910bdeSFrank Jungclaus 			return;
4205e910bdeSFrank Jungclaus 		}
4215e910bdeSFrank Jungclaus 
42280662d94SFrank Jungclaus 		cfd->can_id = id & ESD_USB_IDMASK;
4235e910bdeSFrank Jungclaus 
42480662d94SFrank Jungclaus 		if (msg->rx.dlc & ESD_USB_FD) {
42580662d94SFrank Jungclaus 			/* masking by 0x0F is already done within can_fd_dlc2len() */
42680662d94SFrank Jungclaus 			cfd->len = can_fd_dlc2len(msg->rx.dlc);
42780662d94SFrank Jungclaus 			len = cfd->len;
42880662d94SFrank Jungclaus 			if ((msg->rx.dlc & ESD_USB_NO_BRS) == 0)
42980662d94SFrank Jungclaus 				cfd->flags |= CANFD_BRS;
43080662d94SFrank Jungclaus 			if (msg->rx.dlc & ESD_USB_ESI)
43180662d94SFrank Jungclaus 				cfd->flags |= CANFD_ESI;
43280662d94SFrank Jungclaus 		} else {
43380662d94SFrank Jungclaus 			can_frame_set_cc_len(cf, msg->rx.dlc & ~ESD_USB_RTR, priv->can.ctrlmode);
43480662d94SFrank Jungclaus 			len = cf->len;
4358a99f2adSFrank Jungclaus 			if (msg->rx.dlc & ESD_USB_RTR) {
4365e910bdeSFrank Jungclaus 				cf->can_id |= CAN_RTR_FLAG;
43780662d94SFrank Jungclaus 				len = 0;
4385e910bdeSFrank Jungclaus 			}
43980662d94SFrank Jungclaus 		}
44080662d94SFrank Jungclaus 
44180662d94SFrank Jungclaus 		if (id & ESD_USB_EXTID)
44280662d94SFrank Jungclaus 			cfd->can_id |= CAN_EFF_FLAG;
44380662d94SFrank Jungclaus 
44480662d94SFrank Jungclaus 		memcpy(cfd->data, msg->rx.data_fd, len);
44580662d94SFrank Jungclaus 		stats->rx_bytes += len;
4465e910bdeSFrank Jungclaus 		stats->rx_packets++;
4475e910bdeSFrank Jungclaus 
4485e910bdeSFrank Jungclaus 		netif_rx(skb);
4495e910bdeSFrank Jungclaus 	}
4505e910bdeSFrank Jungclaus }
4515e910bdeSFrank Jungclaus 
esd_usb_tx_done_msg(struct esd_usb_net_priv * priv,union esd_usb_msg * msg)4524d54977fSFrank Jungclaus static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv,
453a57915aeSFrank Jungclaus 				union esd_usb_msg *msg)
4545e910bdeSFrank Jungclaus {
4555e910bdeSFrank Jungclaus 	struct net_device_stats *stats = &priv->netdev->stats;
4565e910bdeSFrank Jungclaus 	struct net_device *netdev = priv->netdev;
4575e910bdeSFrank Jungclaus 	struct esd_tx_urb_context *context;
4585e910bdeSFrank Jungclaus 
4595e910bdeSFrank Jungclaus 	if (!netif_device_present(netdev))
4605e910bdeSFrank Jungclaus 		return;
4615e910bdeSFrank Jungclaus 
4629dc3a695SFrank Jungclaus 	context = &priv->tx_contexts[msg->txdone.hnd & (ESD_USB_MAX_TX_URBS - 1)];
4635e910bdeSFrank Jungclaus 
464a57915aeSFrank Jungclaus 	if (!msg->txdone.status) {
4655e910bdeSFrank Jungclaus 		stats->tx_packets++;
4665e910bdeSFrank Jungclaus 		stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index,
4675e910bdeSFrank Jungclaus 						    NULL);
4685e910bdeSFrank Jungclaus 	} else {
4695e910bdeSFrank Jungclaus 		stats->tx_errors++;
4705e910bdeSFrank Jungclaus 		can_free_echo_skb(netdev, context->echo_index, NULL);
4715e910bdeSFrank Jungclaus 	}
4725e910bdeSFrank Jungclaus 
4735e910bdeSFrank Jungclaus 	/* Release context */
4749dc3a695SFrank Jungclaus 	context->echo_index = ESD_USB_MAX_TX_URBS;
4755e910bdeSFrank Jungclaus 	atomic_dec(&priv->active_tx_jobs);
4765e910bdeSFrank Jungclaus 
4775e910bdeSFrank Jungclaus 	netif_wake_queue(netdev);
4785e910bdeSFrank Jungclaus }
4795e910bdeSFrank Jungclaus 
esd_usb_read_bulk_callback(struct urb * urb)4804d54977fSFrank Jungclaus static void esd_usb_read_bulk_callback(struct urb *urb)
4815e910bdeSFrank Jungclaus {
4824d54977fSFrank Jungclaus 	struct esd_usb *dev = urb->context;
4835e910bdeSFrank Jungclaus 	int retval;
4845e910bdeSFrank Jungclaus 	int pos = 0;
4855e910bdeSFrank Jungclaus 	int i;
4865e910bdeSFrank Jungclaus 
4875e910bdeSFrank Jungclaus 	switch (urb->status) {
4885e910bdeSFrank Jungclaus 	case 0: /* success */
4895e910bdeSFrank Jungclaus 		break;
4905e910bdeSFrank Jungclaus 
4915e910bdeSFrank Jungclaus 	case -ENOENT:
4925e910bdeSFrank Jungclaus 	case -EPIPE:
4935e910bdeSFrank Jungclaus 	case -EPROTO:
4945e910bdeSFrank Jungclaus 	case -ESHUTDOWN:
4955e910bdeSFrank Jungclaus 		return;
4965e910bdeSFrank Jungclaus 
4975e910bdeSFrank Jungclaus 	default:
4985e910bdeSFrank Jungclaus 		dev_info(dev->udev->dev.parent,
4995e910bdeSFrank Jungclaus 			 "Rx URB aborted (%d)\n", urb->status);
5005e910bdeSFrank Jungclaus 		goto resubmit_urb;
5015e910bdeSFrank Jungclaus 	}
5025e910bdeSFrank Jungclaus 
5035e910bdeSFrank Jungclaus 	while (pos < urb->actual_length) {
504a57915aeSFrank Jungclaus 		union esd_usb_msg *msg;
5055e910bdeSFrank Jungclaus 
506a57915aeSFrank Jungclaus 		msg = (union esd_usb_msg *)(urb->transfer_buffer + pos);
5075e910bdeSFrank Jungclaus 
508a57915aeSFrank Jungclaus 		switch (msg->hdr.cmd) {
5099dc3a695SFrank Jungclaus 		case ESD_USB_CMD_CAN_RX:
510a57915aeSFrank Jungclaus 			if (msg->rx.net >= dev->net_count) {
5115e910bdeSFrank Jungclaus 				dev_err(dev->udev->dev.parent, "format error\n");
5125e910bdeSFrank Jungclaus 				break;
5135e910bdeSFrank Jungclaus 			}
5145e910bdeSFrank Jungclaus 
515a57915aeSFrank Jungclaus 			esd_usb_rx_can_msg(dev->nets[msg->rx.net], msg);
5165e910bdeSFrank Jungclaus 			break;
5175e910bdeSFrank Jungclaus 
5189dc3a695SFrank Jungclaus 		case ESD_USB_CMD_CAN_TX:
519a57915aeSFrank Jungclaus 			if (msg->txdone.net >= dev->net_count) {
5205e910bdeSFrank Jungclaus 				dev_err(dev->udev->dev.parent, "format error\n");
5215e910bdeSFrank Jungclaus 				break;
5225e910bdeSFrank Jungclaus 			}
5235e910bdeSFrank Jungclaus 
524a57915aeSFrank Jungclaus 			esd_usb_tx_done_msg(dev->nets[msg->txdone.net],
5255e910bdeSFrank Jungclaus 					    msg);
5265e910bdeSFrank Jungclaus 			break;
5275e910bdeSFrank Jungclaus 		}
5285e910bdeSFrank Jungclaus 
529299a5576SFrank Jungclaus 		pos += msg->hdr.len * sizeof(u32); /* convert to # of bytes */
5305e910bdeSFrank Jungclaus 
5315e910bdeSFrank Jungclaus 		if (pos > urb->actual_length) {
5325e910bdeSFrank Jungclaus 			dev_err(dev->udev->dev.parent, "format error\n");
5335e910bdeSFrank Jungclaus 			break;
5345e910bdeSFrank Jungclaus 		}
5355e910bdeSFrank Jungclaus 	}
5365e910bdeSFrank Jungclaus 
5375e910bdeSFrank Jungclaus resubmit_urb:
5385e910bdeSFrank Jungclaus 	usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
5399dc3a695SFrank Jungclaus 			  urb->transfer_buffer, ESD_USB_RX_BUFFER_SIZE,
5404d54977fSFrank Jungclaus 			  esd_usb_read_bulk_callback, dev);
5415e910bdeSFrank Jungclaus 
5425e910bdeSFrank Jungclaus 	retval = usb_submit_urb(urb, GFP_ATOMIC);
5435e910bdeSFrank Jungclaus 	if (retval == -ENODEV) {
5445e910bdeSFrank Jungclaus 		for (i = 0; i < dev->net_count; i++) {
5455e910bdeSFrank Jungclaus 			if (dev->nets[i])
5465e910bdeSFrank Jungclaus 				netif_device_detach(dev->nets[i]->netdev);
5475e910bdeSFrank Jungclaus 		}
5485e910bdeSFrank Jungclaus 	} else if (retval) {
5495e910bdeSFrank Jungclaus 		dev_err(dev->udev->dev.parent,
5505e910bdeSFrank Jungclaus 			"failed resubmitting read bulk urb: %d\n", retval);
5515e910bdeSFrank Jungclaus 	}
5525e910bdeSFrank Jungclaus }
5535e910bdeSFrank Jungclaus 
55422446100SFrank Jungclaus /* callback for bulk IN urb */
esd_usb_write_bulk_callback(struct urb * urb)5554d54977fSFrank Jungclaus static void esd_usb_write_bulk_callback(struct urb *urb)
5565e910bdeSFrank Jungclaus {
5575e910bdeSFrank Jungclaus 	struct esd_tx_urb_context *context = urb->context;
5584d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv;
5595e910bdeSFrank Jungclaus 	struct net_device *netdev;
560a57915aeSFrank Jungclaus 	size_t size = sizeof(union esd_usb_msg);
5615e910bdeSFrank Jungclaus 
5625e910bdeSFrank Jungclaus 	WARN_ON(!context);
5635e910bdeSFrank Jungclaus 
5645e910bdeSFrank Jungclaus 	priv = context->priv;
5655e910bdeSFrank Jungclaus 	netdev = priv->netdev;
5665e910bdeSFrank Jungclaus 
5675e910bdeSFrank Jungclaus 	/* free up our allocated buffer */
5685e910bdeSFrank Jungclaus 	usb_free_coherent(urb->dev, size,
5695e910bdeSFrank Jungclaus 			  urb->transfer_buffer, urb->transfer_dma);
5705e910bdeSFrank Jungclaus 
5715e910bdeSFrank Jungclaus 	if (!netif_device_present(netdev))
5725e910bdeSFrank Jungclaus 		return;
5735e910bdeSFrank Jungclaus 
5745e910bdeSFrank Jungclaus 	if (urb->status)
5755e910bdeSFrank Jungclaus 		netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
5765e910bdeSFrank Jungclaus 
5775e910bdeSFrank Jungclaus 	netif_trans_update(netdev);
5785e910bdeSFrank Jungclaus }
5795e910bdeSFrank Jungclaus 
firmware_show(struct device * d,struct device_attribute * attr,char * buf)5805e910bdeSFrank Jungclaus static ssize_t firmware_show(struct device *d,
5815e910bdeSFrank Jungclaus 			     struct device_attribute *attr, char *buf)
5825e910bdeSFrank Jungclaus {
5835e910bdeSFrank Jungclaus 	struct usb_interface *intf = to_usb_interface(d);
5844d54977fSFrank Jungclaus 	struct esd_usb *dev = usb_get_intfdata(intf);
5855e910bdeSFrank Jungclaus 
5865e910bdeSFrank Jungclaus 	return sprintf(buf, "%d.%d.%d\n",
5875e910bdeSFrank Jungclaus 		       (dev->version >> 12) & 0xf,
5885e910bdeSFrank Jungclaus 		       (dev->version >> 8) & 0xf,
5895e910bdeSFrank Jungclaus 		       dev->version & 0xff);
5905e910bdeSFrank Jungclaus }
5915e910bdeSFrank Jungclaus static DEVICE_ATTR_RO(firmware);
5925e910bdeSFrank Jungclaus 
hardware_show(struct device * d,struct device_attribute * attr,char * buf)5935e910bdeSFrank Jungclaus static ssize_t hardware_show(struct device *d,
5945e910bdeSFrank Jungclaus 			     struct device_attribute *attr, char *buf)
5955e910bdeSFrank Jungclaus {
5965e910bdeSFrank Jungclaus 	struct usb_interface *intf = to_usb_interface(d);
5974d54977fSFrank Jungclaus 	struct esd_usb *dev = usb_get_intfdata(intf);
5985e910bdeSFrank Jungclaus 
5995e910bdeSFrank Jungclaus 	return sprintf(buf, "%d.%d.%d\n",
6005e910bdeSFrank Jungclaus 		       (dev->version >> 28) & 0xf,
6015e910bdeSFrank Jungclaus 		       (dev->version >> 24) & 0xf,
6025e910bdeSFrank Jungclaus 		       (dev->version >> 16) & 0xff);
6035e910bdeSFrank Jungclaus }
6045e910bdeSFrank Jungclaus static DEVICE_ATTR_RO(hardware);
6055e910bdeSFrank Jungclaus 
nets_show(struct device * d,struct device_attribute * attr,char * buf)6065e910bdeSFrank Jungclaus static ssize_t nets_show(struct device *d,
6075e910bdeSFrank Jungclaus 			 struct device_attribute *attr, char *buf)
6085e910bdeSFrank Jungclaus {
6095e910bdeSFrank Jungclaus 	struct usb_interface *intf = to_usb_interface(d);
6104d54977fSFrank Jungclaus 	struct esd_usb *dev = usb_get_intfdata(intf);
6115e910bdeSFrank Jungclaus 
6125e910bdeSFrank Jungclaus 	return sprintf(buf, "%d", dev->net_count);
6135e910bdeSFrank Jungclaus }
6145e910bdeSFrank Jungclaus static DEVICE_ATTR_RO(nets);
6155e910bdeSFrank Jungclaus 
esd_usb_send_msg(struct esd_usb * dev,union esd_usb_msg * msg)616a57915aeSFrank Jungclaus static int esd_usb_send_msg(struct esd_usb *dev, union esd_usb_msg *msg)
6175e910bdeSFrank Jungclaus {
6185e910bdeSFrank Jungclaus 	int actual_length;
6195e910bdeSFrank Jungclaus 
6205e910bdeSFrank Jungclaus 	return usb_bulk_msg(dev->udev,
6215e910bdeSFrank Jungclaus 			    usb_sndbulkpipe(dev->udev, 2),
6225e910bdeSFrank Jungclaus 			    msg,
623299a5576SFrank Jungclaus 			    msg->hdr.len * sizeof(u32), /* convert to # of bytes */
6245e910bdeSFrank Jungclaus 			    &actual_length,
6255e910bdeSFrank Jungclaus 			    1000);
6265e910bdeSFrank Jungclaus }
6275e910bdeSFrank Jungclaus 
esd_usb_wait_msg(struct esd_usb * dev,union esd_usb_msg * msg)6284d54977fSFrank Jungclaus static int esd_usb_wait_msg(struct esd_usb *dev,
629a57915aeSFrank Jungclaus 			    union esd_usb_msg *msg)
6305e910bdeSFrank Jungclaus {
6315e910bdeSFrank Jungclaus 	int actual_length;
6325e910bdeSFrank Jungclaus 
6335e910bdeSFrank Jungclaus 	return usb_bulk_msg(dev->udev,
6345e910bdeSFrank Jungclaus 			    usb_rcvbulkpipe(dev->udev, 1),
6355e910bdeSFrank Jungclaus 			    msg,
6365e910bdeSFrank Jungclaus 			    sizeof(*msg),
6375e910bdeSFrank Jungclaus 			    &actual_length,
6385e910bdeSFrank Jungclaus 			    1000);
6395e910bdeSFrank Jungclaus }
6405e910bdeSFrank Jungclaus 
esd_usb_setup_rx_urbs(struct esd_usb * dev)6414d54977fSFrank Jungclaus static int esd_usb_setup_rx_urbs(struct esd_usb *dev)
6425e910bdeSFrank Jungclaus {
6435e910bdeSFrank Jungclaus 	int i, err = 0;
6445e910bdeSFrank Jungclaus 
6455e910bdeSFrank Jungclaus 	if (dev->rxinitdone)
6465e910bdeSFrank Jungclaus 		return 0;
6475e910bdeSFrank Jungclaus 
6489dc3a695SFrank Jungclaus 	for (i = 0; i < ESD_USB_MAX_RX_URBS; i++) {
6495e910bdeSFrank Jungclaus 		struct urb *urb = NULL;
6505e910bdeSFrank Jungclaus 		u8 *buf = NULL;
6515e910bdeSFrank Jungclaus 		dma_addr_t buf_dma;
6525e910bdeSFrank Jungclaus 
6535e910bdeSFrank Jungclaus 		/* create a URB, and a buffer for it */
6545e910bdeSFrank Jungclaus 		urb = usb_alloc_urb(0, GFP_KERNEL);
6555e910bdeSFrank Jungclaus 		if (!urb) {
6565e910bdeSFrank Jungclaus 			err = -ENOMEM;
6575e910bdeSFrank Jungclaus 			break;
6585e910bdeSFrank Jungclaus 		}
6595e910bdeSFrank Jungclaus 
6609dc3a695SFrank Jungclaus 		buf = usb_alloc_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE, GFP_KERNEL,
6615e910bdeSFrank Jungclaus 					 &buf_dma);
6625e910bdeSFrank Jungclaus 		if (!buf) {
6635e910bdeSFrank Jungclaus 			dev_warn(dev->udev->dev.parent,
6645e910bdeSFrank Jungclaus 				 "No memory left for USB buffer\n");
6655e910bdeSFrank Jungclaus 			err = -ENOMEM;
6665e910bdeSFrank Jungclaus 			goto freeurb;
6675e910bdeSFrank Jungclaus 		}
6685e910bdeSFrank Jungclaus 
6695e910bdeSFrank Jungclaus 		urb->transfer_dma = buf_dma;
6705e910bdeSFrank Jungclaus 
6715e910bdeSFrank Jungclaus 		usb_fill_bulk_urb(urb, dev->udev,
6725e910bdeSFrank Jungclaus 				  usb_rcvbulkpipe(dev->udev, 1),
6739dc3a695SFrank Jungclaus 				  buf, ESD_USB_RX_BUFFER_SIZE,
6744d54977fSFrank Jungclaus 				  esd_usb_read_bulk_callback, dev);
6755e910bdeSFrank Jungclaus 		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
6765e910bdeSFrank Jungclaus 		usb_anchor_urb(urb, &dev->rx_submitted);
6775e910bdeSFrank Jungclaus 
6785e910bdeSFrank Jungclaus 		err = usb_submit_urb(urb, GFP_KERNEL);
6795e910bdeSFrank Jungclaus 		if (err) {
6805e910bdeSFrank Jungclaus 			usb_unanchor_urb(urb);
6819dc3a695SFrank Jungclaus 			usb_free_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE, buf,
6825e910bdeSFrank Jungclaus 					  urb->transfer_dma);
6835e910bdeSFrank Jungclaus 			goto freeurb;
6845e910bdeSFrank Jungclaus 		}
6855e910bdeSFrank Jungclaus 
6865e910bdeSFrank Jungclaus 		dev->rxbuf[i] = buf;
6875e910bdeSFrank Jungclaus 		dev->rxbuf_dma[i] = buf_dma;
6885e910bdeSFrank Jungclaus 
6895e910bdeSFrank Jungclaus freeurb:
6905e910bdeSFrank Jungclaus 		/* Drop reference, USB core will take care of freeing it */
6915e910bdeSFrank Jungclaus 		usb_free_urb(urb);
6925e910bdeSFrank Jungclaus 		if (err)
6935e910bdeSFrank Jungclaus 			break;
6945e910bdeSFrank Jungclaus 	}
6955e910bdeSFrank Jungclaus 
6965e910bdeSFrank Jungclaus 	/* Did we submit any URBs */
6975e910bdeSFrank Jungclaus 	if (i == 0) {
6985e910bdeSFrank Jungclaus 		dev_err(dev->udev->dev.parent, "couldn't setup read URBs\n");
6995e910bdeSFrank Jungclaus 		return err;
7005e910bdeSFrank Jungclaus 	}
7015e910bdeSFrank Jungclaus 
7025e910bdeSFrank Jungclaus 	/* Warn if we've couldn't transmit all the URBs */
7039dc3a695SFrank Jungclaus 	if (i < ESD_USB_MAX_RX_URBS) {
7045e910bdeSFrank Jungclaus 		dev_warn(dev->udev->dev.parent,
7055e910bdeSFrank Jungclaus 			 "rx performance may be slow\n");
7065e910bdeSFrank Jungclaus 	}
7075e910bdeSFrank Jungclaus 
7085e910bdeSFrank Jungclaus 	dev->rxinitdone = 1;
7095e910bdeSFrank Jungclaus 	return 0;
7105e910bdeSFrank Jungclaus }
7115e910bdeSFrank Jungclaus 
71222446100SFrank Jungclaus /* Start interface */
esd_usb_start(struct esd_usb_net_priv * priv)7134d54977fSFrank Jungclaus static int esd_usb_start(struct esd_usb_net_priv *priv)
7145e910bdeSFrank Jungclaus {
7154d54977fSFrank Jungclaus 	struct esd_usb *dev = priv->usb;
7165e910bdeSFrank Jungclaus 	struct net_device *netdev = priv->netdev;
717a57915aeSFrank Jungclaus 	union esd_usb_msg *msg;
7185e910bdeSFrank Jungclaus 	int err, i;
7195e910bdeSFrank Jungclaus 
7205e910bdeSFrank Jungclaus 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
7215e910bdeSFrank Jungclaus 	if (!msg) {
7225e910bdeSFrank Jungclaus 		err = -ENOMEM;
7235e910bdeSFrank Jungclaus 		goto out;
7245e910bdeSFrank Jungclaus 	}
7255e910bdeSFrank Jungclaus 
72622446100SFrank Jungclaus 	/* Enable all IDs
7275e910bdeSFrank Jungclaus 	 * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
7285e910bdeSFrank Jungclaus 	 * Each bit represents one 11 bit CAN identifier. A set bit
7295e910bdeSFrank Jungclaus 	 * enables reception of the corresponding CAN identifier. A cleared
7305e910bdeSFrank Jungclaus 	 * bit disabled this identifier. An additional bitmask value
7315e910bdeSFrank Jungclaus 	 * following the CAN 2.0A bits is used to enable reception of
7325e910bdeSFrank Jungclaus 	 * extended CAN frames. Only the LSB of this final mask is checked
7335e910bdeSFrank Jungclaus 	 * for the complete 29 bit ID range. The IDADD message also allows
7345e910bdeSFrank Jungclaus 	 * filter configuration for an ID subset. In this case you can add
7355e910bdeSFrank Jungclaus 	 * the number of the starting bitmask (0..64) to the filter.option
7365e910bdeSFrank Jungclaus 	 * field followed by only some bitmasks.
7375e910bdeSFrank Jungclaus 	 */
7389dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_IDADD;
739299a5576SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_id_filter_msg) / sizeof(u32); /* # of 32bit words */
740a57915aeSFrank Jungclaus 	msg->filter.net = priv->index;
7419dc3a695SFrank Jungclaus 	msg->filter.option = ESD_USB_ID_ENABLE; /* start with segment 0 */
7429dc3a695SFrank Jungclaus 	for (i = 0; i < ESD_USB_MAX_ID_SEGMENT; i++)
74333665fdbSFrank Jungclaus 		msg->filter.mask[i] = cpu_to_le32(GENMASK(31, 0));
7445e910bdeSFrank Jungclaus 	/* enable 29bit extended IDs */
74533665fdbSFrank Jungclaus 	msg->filter.mask[ESD_USB_MAX_ID_SEGMENT] = cpu_to_le32(BIT(0));
7465e910bdeSFrank Jungclaus 
7474d54977fSFrank Jungclaus 	err = esd_usb_send_msg(dev, msg);
7485e910bdeSFrank Jungclaus 	if (err)
7495e910bdeSFrank Jungclaus 		goto out;
7505e910bdeSFrank Jungclaus 
7514d54977fSFrank Jungclaus 	err = esd_usb_setup_rx_urbs(dev);
7525e910bdeSFrank Jungclaus 	if (err)
7535e910bdeSFrank Jungclaus 		goto out;
7545e910bdeSFrank Jungclaus 
7555e910bdeSFrank Jungclaus 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
7565e910bdeSFrank Jungclaus 
7575e910bdeSFrank Jungclaus out:
7585e910bdeSFrank Jungclaus 	if (err == -ENODEV)
7595e910bdeSFrank Jungclaus 		netif_device_detach(netdev);
7605e910bdeSFrank Jungclaus 	if (err)
7615e910bdeSFrank Jungclaus 		netdev_err(netdev, "couldn't start device: %d\n", err);
7625e910bdeSFrank Jungclaus 
7635e910bdeSFrank Jungclaus 	kfree(msg);
7645e910bdeSFrank Jungclaus 	return err;
7655e910bdeSFrank Jungclaus }
7665e910bdeSFrank Jungclaus 
unlink_all_urbs(struct esd_usb * dev)7674d54977fSFrank Jungclaus static void unlink_all_urbs(struct esd_usb *dev)
7685e910bdeSFrank Jungclaus {
7694d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv;
7705e910bdeSFrank Jungclaus 	int i, j;
7715e910bdeSFrank Jungclaus 
7725e910bdeSFrank Jungclaus 	usb_kill_anchored_urbs(&dev->rx_submitted);
7735e910bdeSFrank Jungclaus 
7749dc3a695SFrank Jungclaus 	for (i = 0; i < ESD_USB_MAX_RX_URBS; ++i)
7759dc3a695SFrank Jungclaus 		usb_free_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE,
7765e910bdeSFrank Jungclaus 				  dev->rxbuf[i], dev->rxbuf_dma[i]);
7775e910bdeSFrank Jungclaus 
7785e910bdeSFrank Jungclaus 	for (i = 0; i < dev->net_count; i++) {
7795e910bdeSFrank Jungclaus 		priv = dev->nets[i];
7805e910bdeSFrank Jungclaus 		if (priv) {
7815e910bdeSFrank Jungclaus 			usb_kill_anchored_urbs(&priv->tx_submitted);
7825e910bdeSFrank Jungclaus 			atomic_set(&priv->active_tx_jobs, 0);
7835e910bdeSFrank Jungclaus 
7849dc3a695SFrank Jungclaus 			for (j = 0; j < ESD_USB_MAX_TX_URBS; j++)
7859dc3a695SFrank Jungclaus 				priv->tx_contexts[j].echo_index = ESD_USB_MAX_TX_URBS;
7865e910bdeSFrank Jungclaus 		}
7875e910bdeSFrank Jungclaus 	}
7885e910bdeSFrank Jungclaus }
7895e910bdeSFrank Jungclaus 
esd_usb_open(struct net_device * netdev)7904d54977fSFrank Jungclaus static int esd_usb_open(struct net_device *netdev)
7915e910bdeSFrank Jungclaus {
7924d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
7935e910bdeSFrank Jungclaus 	int err;
7945e910bdeSFrank Jungclaus 
7955e910bdeSFrank Jungclaus 	/* common open */
7965e910bdeSFrank Jungclaus 	err = open_candev(netdev);
7975e910bdeSFrank Jungclaus 	if (err)
7985e910bdeSFrank Jungclaus 		return err;
7995e910bdeSFrank Jungclaus 
8005e910bdeSFrank Jungclaus 	/* finally start device */
8014d54977fSFrank Jungclaus 	err = esd_usb_start(priv);
8025e910bdeSFrank Jungclaus 	if (err) {
8035e910bdeSFrank Jungclaus 		netdev_warn(netdev, "couldn't start device: %d\n", err);
8045e910bdeSFrank Jungclaus 		close_candev(netdev);
8055e910bdeSFrank Jungclaus 		return err;
8065e910bdeSFrank Jungclaus 	}
8075e910bdeSFrank Jungclaus 
8085e910bdeSFrank Jungclaus 	netif_start_queue(netdev);
8095e910bdeSFrank Jungclaus 
8105e910bdeSFrank Jungclaus 	return 0;
8115e910bdeSFrank Jungclaus }
8125e910bdeSFrank Jungclaus 
esd_usb_start_xmit(struct sk_buff * skb,struct net_device * netdev)8134d54977fSFrank Jungclaus static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
8145e910bdeSFrank Jungclaus 				      struct net_device *netdev)
8155e910bdeSFrank Jungclaus {
8164d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
8174d54977fSFrank Jungclaus 	struct esd_usb *dev = priv->usb;
8185e910bdeSFrank Jungclaus 	struct esd_tx_urb_context *context = NULL;
8195e910bdeSFrank Jungclaus 	struct net_device_stats *stats = &netdev->stats;
82080662d94SFrank Jungclaus 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
821a57915aeSFrank Jungclaus 	union esd_usb_msg *msg;
8225e910bdeSFrank Jungclaus 	struct urb *urb;
8235e910bdeSFrank Jungclaus 	u8 *buf;
8245e910bdeSFrank Jungclaus 	int i, err;
8255e910bdeSFrank Jungclaus 	int ret = NETDEV_TX_OK;
826a57915aeSFrank Jungclaus 	size_t size = sizeof(union esd_usb_msg);
8275e910bdeSFrank Jungclaus 
828ae64438bSOliver Hartkopp 	if (can_dev_dropped_skb(netdev, skb))
8295e910bdeSFrank Jungclaus 		return NETDEV_TX_OK;
8305e910bdeSFrank Jungclaus 
8315e910bdeSFrank Jungclaus 	/* create a URB, and a buffer for it, and copy the data to the URB */
8325e910bdeSFrank Jungclaus 	urb = usb_alloc_urb(0, GFP_ATOMIC);
8335e910bdeSFrank Jungclaus 	if (!urb) {
8345e910bdeSFrank Jungclaus 		stats->tx_dropped++;
8355e910bdeSFrank Jungclaus 		dev_kfree_skb(skb);
8365e910bdeSFrank Jungclaus 		goto nourbmem;
8375e910bdeSFrank Jungclaus 	}
8385e910bdeSFrank Jungclaus 
8395e910bdeSFrank Jungclaus 	buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC,
8405e910bdeSFrank Jungclaus 				 &urb->transfer_dma);
8415e910bdeSFrank Jungclaus 	if (!buf) {
8425e910bdeSFrank Jungclaus 		netdev_err(netdev, "No memory left for USB buffer\n");
8435e910bdeSFrank Jungclaus 		stats->tx_dropped++;
8445e910bdeSFrank Jungclaus 		dev_kfree_skb(skb);
8455e910bdeSFrank Jungclaus 		goto nobufmem;
8465e910bdeSFrank Jungclaus 	}
8475e910bdeSFrank Jungclaus 
848a57915aeSFrank Jungclaus 	msg = (union esd_usb_msg *)buf;
8495e910bdeSFrank Jungclaus 
850299a5576SFrank Jungclaus 	/* minimal length as # of 32bit words */
851299a5576SFrank Jungclaus 	msg->hdr.len = offsetof(struct esd_usb_tx_msg, data) / sizeof(u32);
8529dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_CAN_TX;
853a57915aeSFrank Jungclaus 	msg->tx.net = priv->index;
8545e910bdeSFrank Jungclaus 
85580662d94SFrank Jungclaus 	if (can_is_canfd_skb(skb)) {
85680662d94SFrank Jungclaus 		msg->tx.dlc = can_fd_len2dlc(cfd->len);
85780662d94SFrank Jungclaus 		msg->tx.dlc |= ESD_USB_FD;
85880662d94SFrank Jungclaus 
85980662d94SFrank Jungclaus 		if ((cfd->flags & CANFD_BRS) == 0)
86080662d94SFrank Jungclaus 			msg->tx.dlc |= ESD_USB_NO_BRS;
86180662d94SFrank Jungclaus 	} else {
86280662d94SFrank Jungclaus 		msg->tx.dlc = can_get_cc_dlc((struct can_frame *)cfd, priv->can.ctrlmode);
86380662d94SFrank Jungclaus 
86480662d94SFrank Jungclaus 		if (cfd->can_id & CAN_RTR_FLAG)
8658a99f2adSFrank Jungclaus 			msg->tx.dlc |= ESD_USB_RTR;
86680662d94SFrank Jungclaus 	}
8675e910bdeSFrank Jungclaus 
86880662d94SFrank Jungclaus 	msg->tx.id = cpu_to_le32(cfd->can_id & CAN_ERR_MASK);
86980662d94SFrank Jungclaus 
87080662d94SFrank Jungclaus 	if (cfd->can_id & CAN_EFF_FLAG)
8719dc3a695SFrank Jungclaus 		msg->tx.id |= cpu_to_le32(ESD_USB_EXTID);
8725e910bdeSFrank Jungclaus 
87380662d94SFrank Jungclaus 	memcpy(msg->tx.data_fd, cfd->data, cfd->len);
8745e910bdeSFrank Jungclaus 
875299a5576SFrank Jungclaus 	/* round up, then divide by 4 to add the payload length as # of 32bit words */
87680662d94SFrank Jungclaus 	msg->hdr.len += DIV_ROUND_UP(cfd->len, sizeof(u32));
8775e910bdeSFrank Jungclaus 
8789dc3a695SFrank Jungclaus 	for (i = 0; i < ESD_USB_MAX_TX_URBS; i++) {
8799dc3a695SFrank Jungclaus 		if (priv->tx_contexts[i].echo_index == ESD_USB_MAX_TX_URBS) {
8805e910bdeSFrank Jungclaus 			context = &priv->tx_contexts[i];
8815e910bdeSFrank Jungclaus 			break;
8825e910bdeSFrank Jungclaus 		}
8835e910bdeSFrank Jungclaus 	}
8845e910bdeSFrank Jungclaus 
88522446100SFrank Jungclaus 	/* This may never happen */
8865e910bdeSFrank Jungclaus 	if (!context) {
8875e910bdeSFrank Jungclaus 		netdev_warn(netdev, "couldn't find free context\n");
8885e910bdeSFrank Jungclaus 		ret = NETDEV_TX_BUSY;
8895e910bdeSFrank Jungclaus 		goto releasebuf;
8905e910bdeSFrank Jungclaus 	}
8915e910bdeSFrank Jungclaus 
8925e910bdeSFrank Jungclaus 	context->priv = priv;
8935e910bdeSFrank Jungclaus 	context->echo_index = i;
8945e910bdeSFrank Jungclaus 
8955e910bdeSFrank Jungclaus 	/* hnd must not be 0 - MSB is stripped in txdone handling */
89633665fdbSFrank Jungclaus 	msg->tx.hnd = BIT(31) | i; /* returned in TX done message */
8975e910bdeSFrank Jungclaus 
8985e910bdeSFrank Jungclaus 	usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
899299a5576SFrank Jungclaus 			  msg->hdr.len * sizeof(u32), /* convert to # of bytes */
9004d54977fSFrank Jungclaus 			  esd_usb_write_bulk_callback, context);
9015e910bdeSFrank Jungclaus 
9025e910bdeSFrank Jungclaus 	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
9035e910bdeSFrank Jungclaus 
9045e910bdeSFrank Jungclaus 	usb_anchor_urb(urb, &priv->tx_submitted);
9055e910bdeSFrank Jungclaus 
9065e910bdeSFrank Jungclaus 	can_put_echo_skb(skb, netdev, context->echo_index, 0);
9075e910bdeSFrank Jungclaus 
9085e910bdeSFrank Jungclaus 	atomic_inc(&priv->active_tx_jobs);
9095e910bdeSFrank Jungclaus 
9105e910bdeSFrank Jungclaus 	/* Slow down tx path */
9119dc3a695SFrank Jungclaus 	if (atomic_read(&priv->active_tx_jobs) >= ESD_USB_MAX_TX_URBS)
9125e910bdeSFrank Jungclaus 		netif_stop_queue(netdev);
9135e910bdeSFrank Jungclaus 
9145e910bdeSFrank Jungclaus 	err = usb_submit_urb(urb, GFP_ATOMIC);
9155e910bdeSFrank Jungclaus 	if (err) {
9165e910bdeSFrank Jungclaus 		can_free_echo_skb(netdev, context->echo_index, NULL);
9175e910bdeSFrank Jungclaus 
9185e910bdeSFrank Jungclaus 		atomic_dec(&priv->active_tx_jobs);
9195e910bdeSFrank Jungclaus 		usb_unanchor_urb(urb);
9205e910bdeSFrank Jungclaus 
9215e910bdeSFrank Jungclaus 		stats->tx_dropped++;
9225e910bdeSFrank Jungclaus 
9235e910bdeSFrank Jungclaus 		if (err == -ENODEV)
9245e910bdeSFrank Jungclaus 			netif_device_detach(netdev);
9255e910bdeSFrank Jungclaus 		else
9265e910bdeSFrank Jungclaus 			netdev_warn(netdev, "failed tx_urb %d\n", err);
9275e910bdeSFrank Jungclaus 
9285e910bdeSFrank Jungclaus 		goto releasebuf;
9295e910bdeSFrank Jungclaus 	}
9305e910bdeSFrank Jungclaus 
9315e910bdeSFrank Jungclaus 	netif_trans_update(netdev);
9325e910bdeSFrank Jungclaus 
93322446100SFrank Jungclaus 	/* Release our reference to this URB, the USB core will eventually free
9345e910bdeSFrank Jungclaus 	 * it entirely.
9355e910bdeSFrank Jungclaus 	 */
9365e910bdeSFrank Jungclaus 	usb_free_urb(urb);
9375e910bdeSFrank Jungclaus 
9385e910bdeSFrank Jungclaus 	return NETDEV_TX_OK;
9395e910bdeSFrank Jungclaus 
9405e910bdeSFrank Jungclaus releasebuf:
9415e910bdeSFrank Jungclaus 	usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
9425e910bdeSFrank Jungclaus 
9435e910bdeSFrank Jungclaus nobufmem:
9445e910bdeSFrank Jungclaus 	usb_free_urb(urb);
9455e910bdeSFrank Jungclaus 
9465e910bdeSFrank Jungclaus nourbmem:
9475e910bdeSFrank Jungclaus 	return ret;
9485e910bdeSFrank Jungclaus }
9495e910bdeSFrank Jungclaus 
esd_usb_close(struct net_device * netdev)9504d54977fSFrank Jungclaus static int esd_usb_close(struct net_device *netdev)
9515e910bdeSFrank Jungclaus {
9524d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
953a57915aeSFrank Jungclaus 	union esd_usb_msg *msg;
9545e910bdeSFrank Jungclaus 	int i;
9555e910bdeSFrank Jungclaus 
9565e910bdeSFrank Jungclaus 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
9575e910bdeSFrank Jungclaus 	if (!msg)
9585e910bdeSFrank Jungclaus 		return -ENOMEM;
9595e910bdeSFrank Jungclaus 
9604d54977fSFrank Jungclaus 	/* Disable all IDs (see esd_usb_start()) */
9619dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_IDADD;
962299a5576SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_id_filter_msg) / sizeof(u32);/* # of 32bit words */
963a57915aeSFrank Jungclaus 	msg->filter.net = priv->index;
9649dc3a695SFrank Jungclaus 	msg->filter.option = ESD_USB_ID_ENABLE; /* start with segment 0 */
9659dc3a695SFrank Jungclaus 	for (i = 0; i <= ESD_USB_MAX_ID_SEGMENT; i++)
966a57915aeSFrank Jungclaus 		msg->filter.mask[i] = 0;
9674d54977fSFrank Jungclaus 	if (esd_usb_send_msg(priv->usb, msg) < 0)
9685e910bdeSFrank Jungclaus 		netdev_err(netdev, "sending idadd message failed\n");
9695e910bdeSFrank Jungclaus 
9705e910bdeSFrank Jungclaus 	/* set CAN controller to reset mode */
971299a5576SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */
9729dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_SETBAUD;
973a57915aeSFrank Jungclaus 	msg->setbaud.net = priv->index;
974a57915aeSFrank Jungclaus 	msg->setbaud.rsvd = 0;
975a57915aeSFrank Jungclaus 	msg->setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE);
9764d54977fSFrank Jungclaus 	if (esd_usb_send_msg(priv->usb, msg) < 0)
9775e910bdeSFrank Jungclaus 		netdev_err(netdev, "sending setbaud message failed\n");
9785e910bdeSFrank Jungclaus 
9795e910bdeSFrank Jungclaus 	priv->can.state = CAN_STATE_STOPPED;
9805e910bdeSFrank Jungclaus 
9815e910bdeSFrank Jungclaus 	netif_stop_queue(netdev);
9825e910bdeSFrank Jungclaus 
9835e910bdeSFrank Jungclaus 	close_candev(netdev);
9845e910bdeSFrank Jungclaus 
9855e910bdeSFrank Jungclaus 	kfree(msg);
9865e910bdeSFrank Jungclaus 
9875e910bdeSFrank Jungclaus 	return 0;
9885e910bdeSFrank Jungclaus }
9895e910bdeSFrank Jungclaus 
9904d54977fSFrank Jungclaus static const struct net_device_ops esd_usb_netdev_ops = {
9914d54977fSFrank Jungclaus 	.ndo_open = esd_usb_open,
9924d54977fSFrank Jungclaus 	.ndo_stop = esd_usb_close,
9934d54977fSFrank Jungclaus 	.ndo_start_xmit = esd_usb_start_xmit,
9945e910bdeSFrank Jungclaus 	.ndo_change_mtu = can_change_mtu,
9955e910bdeSFrank Jungclaus };
9965e910bdeSFrank Jungclaus 
997409c188cSVincent Mailhol static const struct ethtool_ops esd_usb_ethtool_ops = {
998409c188cSVincent Mailhol 	.get_ts_info = ethtool_op_get_ts_info,
999409c188cSVincent Mailhol };
1000409c188cSVincent Mailhol 
10018ef426e1SFrank Jungclaus static const struct can_bittiming_const esd_usb_2_bittiming_const = {
10028ef426e1SFrank Jungclaus 	.name = "esd_usb_2",
10035a4dd879SFrank Jungclaus 	.tseg1_min = 1,
10045a4dd879SFrank Jungclaus 	.tseg1_max = 16,
10055a4dd879SFrank Jungclaus 	.tseg2_min = 1,
10065a4dd879SFrank Jungclaus 	.tseg2_max = 8,
10075a4dd879SFrank Jungclaus 	.sjw_max = 4,
10085a4dd879SFrank Jungclaus 	.brp_min = 1,
10095a4dd879SFrank Jungclaus 	.brp_max = 1024,
10105a4dd879SFrank Jungclaus 	.brp_inc = 1,
10115e910bdeSFrank Jungclaus };
10125e910bdeSFrank Jungclaus 
esd_usb_2_set_bittiming(struct net_device * netdev)10138ef426e1SFrank Jungclaus static int esd_usb_2_set_bittiming(struct net_device *netdev)
10145e910bdeSFrank Jungclaus {
10158ef426e1SFrank Jungclaus 	const struct can_bittiming_const *btc = &esd_usb_2_bittiming_const;
10164d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
10175e910bdeSFrank Jungclaus 	struct can_bittiming *bt = &priv->can.bittiming;
1018a57915aeSFrank Jungclaus 	union esd_usb_msg *msg;
10195e910bdeSFrank Jungclaus 	int err;
10205e910bdeSFrank Jungclaus 	u32 canbtr;
10215e910bdeSFrank Jungclaus 	int sjw_shift;
10225e910bdeSFrank Jungclaus 
10234d54977fSFrank Jungclaus 	canbtr = ESD_USB_UBR;
10245e910bdeSFrank Jungclaus 	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
10254d54977fSFrank Jungclaus 		canbtr |= ESD_USB_LOM;
10265e910bdeSFrank Jungclaus 
10275a4dd879SFrank Jungclaus 	canbtr |= (bt->brp - 1) & (btc->brp_max - 1);
10285e910bdeSFrank Jungclaus 
10294d54977fSFrank Jungclaus 	if (le16_to_cpu(priv->usb->udev->descriptor.idProduct) ==
10309dc3a695SFrank Jungclaus 	    ESD_USB_CANUSBM_PRODUCT_ID)
10319dc3a695SFrank Jungclaus 		sjw_shift = ESD_USB_M_SJW_SHIFT;
10325e910bdeSFrank Jungclaus 	else
10339dc3a695SFrank Jungclaus 		sjw_shift = ESD_USB_2_SJW_SHIFT;
10345e910bdeSFrank Jungclaus 
10355a4dd879SFrank Jungclaus 	canbtr |= ((bt->sjw - 1) & (btc->sjw_max - 1))
10365e910bdeSFrank Jungclaus 		<< sjw_shift;
10375e910bdeSFrank Jungclaus 	canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1)
10385a4dd879SFrank Jungclaus 		   & (btc->tseg1_max - 1))
10399dc3a695SFrank Jungclaus 		<< ESD_USB_2_TSEG1_SHIFT;
10405a4dd879SFrank Jungclaus 	canbtr |= ((bt->phase_seg2 - 1) & (btc->tseg2_max - 1))
10419dc3a695SFrank Jungclaus 		<< ESD_USB_2_TSEG2_SHIFT;
10425e910bdeSFrank Jungclaus 	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
10439dc3a695SFrank Jungclaus 		canbtr |= ESD_USB_TRIPLE_SAMPLES;
10445e910bdeSFrank Jungclaus 
10455e910bdeSFrank Jungclaus 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
10465e910bdeSFrank Jungclaus 	if (!msg)
10475e910bdeSFrank Jungclaus 		return -ENOMEM;
10485e910bdeSFrank Jungclaus 
1049299a5576SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */
10509dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_SETBAUD;
1051a57915aeSFrank Jungclaus 	msg->setbaud.net = priv->index;
1052a57915aeSFrank Jungclaus 	msg->setbaud.rsvd = 0;
1053a57915aeSFrank Jungclaus 	msg->setbaud.baud = cpu_to_le32(canbtr);
10545e910bdeSFrank Jungclaus 
10551336ca2dSFrank Jungclaus 	netdev_dbg(netdev, "setting BTR=%#x\n", canbtr);
10565e910bdeSFrank Jungclaus 
10574d54977fSFrank Jungclaus 	err = esd_usb_send_msg(priv->usb, msg);
10585e910bdeSFrank Jungclaus 
10595e910bdeSFrank Jungclaus 	kfree(msg);
10605e910bdeSFrank Jungclaus 	return err;
10615e910bdeSFrank Jungclaus }
10625e910bdeSFrank Jungclaus 
106380662d94SFrank Jungclaus /* Nominal bittiming constants, see
106480662d94SFrank Jungclaus  * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022
106580662d94SFrank Jungclaus  * 48.6.8 MCAN Nominal Bit Timing and Prescaler Register
106680662d94SFrank Jungclaus  */
106780662d94SFrank Jungclaus static const struct can_bittiming_const esd_usb_3_nom_bittiming_const = {
106880662d94SFrank Jungclaus 	.name = "esd_usb_3",
106980662d94SFrank Jungclaus 	.tseg1_min = 2,
107080662d94SFrank Jungclaus 	.tseg1_max = 256,
107180662d94SFrank Jungclaus 	.tseg2_min = 2,
107280662d94SFrank Jungclaus 	.tseg2_max = 128,
107380662d94SFrank Jungclaus 	.sjw_max = 128,
107480662d94SFrank Jungclaus 	.brp_min = 1,
107580662d94SFrank Jungclaus 	.brp_max = 512,
107680662d94SFrank Jungclaus 	.brp_inc = 1,
107780662d94SFrank Jungclaus };
107880662d94SFrank Jungclaus 
107980662d94SFrank Jungclaus /* Data bittiming constants, see
108080662d94SFrank Jungclaus  * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022
108180662d94SFrank Jungclaus  * 48.6.4 MCAN Data Bit Timing and Prescaler Register
108280662d94SFrank Jungclaus  */
108380662d94SFrank Jungclaus static const struct can_bittiming_const esd_usb_3_data_bittiming_const = {
108480662d94SFrank Jungclaus 	.name = "esd_usb_3",
108580662d94SFrank Jungclaus 	.tseg1_min = 2,
108680662d94SFrank Jungclaus 	.tseg1_max = 32,
108780662d94SFrank Jungclaus 	.tseg2_min = 1,
108880662d94SFrank Jungclaus 	.tseg2_max = 16,
108980662d94SFrank Jungclaus 	.sjw_max = 8,
109080662d94SFrank Jungclaus 	.brp_min = 1,
109180662d94SFrank Jungclaus 	.brp_max = 32,
109280662d94SFrank Jungclaus 	.brp_inc = 1,
109380662d94SFrank Jungclaus };
109480662d94SFrank Jungclaus 
esd_usb_3_set_bittiming(struct net_device * netdev)109580662d94SFrank Jungclaus static int esd_usb_3_set_bittiming(struct net_device *netdev)
109680662d94SFrank Jungclaus {
109780662d94SFrank Jungclaus 	const struct can_bittiming_const *nom_btc = &esd_usb_3_nom_bittiming_const;
109880662d94SFrank Jungclaus 	const struct can_bittiming_const *data_btc = &esd_usb_3_data_bittiming_const;
109980662d94SFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
110080662d94SFrank Jungclaus 	struct can_bittiming *nom_bt = &priv->can.bittiming;
110180662d94SFrank Jungclaus 	struct can_bittiming *data_bt = &priv->can.data_bittiming;
110280662d94SFrank Jungclaus 	struct esd_usb_3_set_baudrate_msg_x *baud_x;
110380662d94SFrank Jungclaus 	union esd_usb_msg *msg;
110480662d94SFrank Jungclaus 	u16 flags = 0;
110580662d94SFrank Jungclaus 	int err;
110680662d94SFrank Jungclaus 
110780662d94SFrank Jungclaus 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
110880662d94SFrank Jungclaus 	if (!msg)
110980662d94SFrank Jungclaus 		return -ENOMEM;
111080662d94SFrank Jungclaus 
111180662d94SFrank Jungclaus 	baud_x = &msg->setbaud_x;
111280662d94SFrank Jungclaus 
111380662d94SFrank Jungclaus 	/* Canonical is the most reasonable mode for SocketCAN on CAN-USB/3 ... */
111480662d94SFrank Jungclaus 	baud_x->mode = cpu_to_le16(ESD_USB_3_BAUDRATE_MODE_BTR_CANONICAL);
111580662d94SFrank Jungclaus 
111680662d94SFrank Jungclaus 	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
111780662d94SFrank Jungclaus 		flags |= ESD_USB_3_BAUDRATE_FLAG_LOM;
111880662d94SFrank Jungclaus 
111980662d94SFrank Jungclaus 	baud_x->nom.brp = cpu_to_le16(nom_bt->brp & (nom_btc->brp_max - 1));
112080662d94SFrank Jungclaus 	baud_x->nom.sjw = cpu_to_le16(nom_bt->sjw & (nom_btc->sjw_max - 1));
112180662d94SFrank Jungclaus 	baud_x->nom.tseg1 = cpu_to_le16((nom_bt->prop_seg + nom_bt->phase_seg1)
112280662d94SFrank Jungclaus 					& (nom_btc->tseg1_max - 1));
112380662d94SFrank Jungclaus 	baud_x->nom.tseg2 = cpu_to_le16(nom_bt->phase_seg2 & (nom_btc->tseg2_max - 1));
112480662d94SFrank Jungclaus 
112580662d94SFrank Jungclaus 	if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
112680662d94SFrank Jungclaus 		baud_x->data.brp = cpu_to_le16(data_bt->brp & (data_btc->brp_max - 1));
112780662d94SFrank Jungclaus 		baud_x->data.sjw = cpu_to_le16(data_bt->sjw & (data_btc->sjw_max - 1));
112880662d94SFrank Jungclaus 		baud_x->data.tseg1 = cpu_to_le16((data_bt->prop_seg + data_bt->phase_seg1)
112980662d94SFrank Jungclaus 						 & (data_btc->tseg1_max - 1));
113080662d94SFrank Jungclaus 		baud_x->data.tseg2 = cpu_to_le16(data_bt->phase_seg2 & (data_btc->tseg2_max - 1));
113180662d94SFrank Jungclaus 		flags |= ESD_USB_3_BAUDRATE_FLAG_FD;
113280662d94SFrank Jungclaus 	}
113380662d94SFrank Jungclaus 
113480662d94SFrank Jungclaus 	/* Currently this driver only supports the automatic TDC mode */
113580662d94SFrank Jungclaus 	baud_x->tdc.tdc_mode = ESD_USB_3_TDC_MODE_AUTO;
113680662d94SFrank Jungclaus 	baud_x->tdc.ssp_offset = 0;
113780662d94SFrank Jungclaus 	baud_x->tdc.ssp_shift = 0;
113880662d94SFrank Jungclaus 	baud_x->tdc.tdc_filter = 0;
113980662d94SFrank Jungclaus 
114080662d94SFrank Jungclaus 	baud_x->flags = cpu_to_le16(flags);
114180662d94SFrank Jungclaus 	baud_x->net = priv->index;
114280662d94SFrank Jungclaus 	baud_x->rsvd = 0;
114380662d94SFrank Jungclaus 
114480662d94SFrank Jungclaus 	/* set len as # of 32bit words */
114580662d94SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_3_set_baudrate_msg_x) / sizeof(u32);
114680662d94SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_SETBAUD;
114780662d94SFrank Jungclaus 
114880662d94SFrank Jungclaus 	netdev_dbg(netdev,
114980662d94SFrank Jungclaus 		   "ctrlmode=%#x/%#x, esd-net=%u, esd-mode=%#x, esd-flags=%#x\n",
115080662d94SFrank Jungclaus 		   priv->can.ctrlmode, priv->can.ctrlmode_supported,
115180662d94SFrank Jungclaus 		   priv->index, le16_to_cpu(baud_x->mode), flags);
115280662d94SFrank Jungclaus 
115380662d94SFrank Jungclaus 	err = esd_usb_send_msg(priv->usb, msg);
115480662d94SFrank Jungclaus 
115580662d94SFrank Jungclaus 	kfree(msg);
115680662d94SFrank Jungclaus 	return err;
115780662d94SFrank Jungclaus }
115880662d94SFrank Jungclaus 
esd_usb_get_berr_counter(const struct net_device * netdev,struct can_berr_counter * bec)11594d54977fSFrank Jungclaus static int esd_usb_get_berr_counter(const struct net_device *netdev,
11605e910bdeSFrank Jungclaus 				    struct can_berr_counter *bec)
11615e910bdeSFrank Jungclaus {
11624d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv = netdev_priv(netdev);
11635e910bdeSFrank Jungclaus 
11645e910bdeSFrank Jungclaus 	bec->txerr = priv->bec.txerr;
11655e910bdeSFrank Jungclaus 	bec->rxerr = priv->bec.rxerr;
11665e910bdeSFrank Jungclaus 
11675e910bdeSFrank Jungclaus 	return 0;
11685e910bdeSFrank Jungclaus }
11695e910bdeSFrank Jungclaus 
esd_usb_set_mode(struct net_device * netdev,enum can_mode mode)11704d54977fSFrank Jungclaus static int esd_usb_set_mode(struct net_device *netdev, enum can_mode mode)
11715e910bdeSFrank Jungclaus {
11725e910bdeSFrank Jungclaus 	switch (mode) {
11735e910bdeSFrank Jungclaus 	case CAN_MODE_START:
11745e910bdeSFrank Jungclaus 		netif_wake_queue(netdev);
11755e910bdeSFrank Jungclaus 		break;
11765e910bdeSFrank Jungclaus 
11775e910bdeSFrank Jungclaus 	default:
11785e910bdeSFrank Jungclaus 		return -EOPNOTSUPP;
11795e910bdeSFrank Jungclaus 	}
11805e910bdeSFrank Jungclaus 
11815e910bdeSFrank Jungclaus 	return 0;
11825e910bdeSFrank Jungclaus }
11835e910bdeSFrank Jungclaus 
esd_usb_probe_one_net(struct usb_interface * intf,int index)11844d54977fSFrank Jungclaus static int esd_usb_probe_one_net(struct usb_interface *intf, int index)
11855e910bdeSFrank Jungclaus {
11864d54977fSFrank Jungclaus 	struct esd_usb *dev = usb_get_intfdata(intf);
11875e910bdeSFrank Jungclaus 	struct net_device *netdev;
11884d54977fSFrank Jungclaus 	struct esd_usb_net_priv *priv;
11895e910bdeSFrank Jungclaus 	int err = 0;
11905e910bdeSFrank Jungclaus 	int i;
11915e910bdeSFrank Jungclaus 
11929dc3a695SFrank Jungclaus 	netdev = alloc_candev(sizeof(*priv), ESD_USB_MAX_TX_URBS);
11935e910bdeSFrank Jungclaus 	if (!netdev) {
11945e910bdeSFrank Jungclaus 		dev_err(&intf->dev, "couldn't alloc candev\n");
11955e910bdeSFrank Jungclaus 		err = -ENOMEM;
11965e910bdeSFrank Jungclaus 		goto done;
11975e910bdeSFrank Jungclaus 	}
11985e910bdeSFrank Jungclaus 
11995e910bdeSFrank Jungclaus 	priv = netdev_priv(netdev);
12005e910bdeSFrank Jungclaus 
12015e910bdeSFrank Jungclaus 	init_usb_anchor(&priv->tx_submitted);
12025e910bdeSFrank Jungclaus 	atomic_set(&priv->active_tx_jobs, 0);
12035e910bdeSFrank Jungclaus 
12049dc3a695SFrank Jungclaus 	for (i = 0; i < ESD_USB_MAX_TX_URBS; i++)
12059dc3a695SFrank Jungclaus 		priv->tx_contexts[i].echo_index = ESD_USB_MAX_TX_URBS;
12065e910bdeSFrank Jungclaus 
12074d54977fSFrank Jungclaus 	priv->usb = dev;
12085e910bdeSFrank Jungclaus 	priv->netdev = netdev;
12095e910bdeSFrank Jungclaus 	priv->index = index;
12105e910bdeSFrank Jungclaus 
12115e910bdeSFrank Jungclaus 	priv->can.state = CAN_STATE_STOPPED;
12125e910bdeSFrank Jungclaus 	priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
1213c42fc369SFrank Jungclaus 		CAN_CTRLMODE_CC_LEN8_DLC |
1214c42fc369SFrank Jungclaus 		CAN_CTRLMODE_BERR_REPORTING;
12155e910bdeSFrank Jungclaus 
121680662d94SFrank Jungclaus 	switch (le16_to_cpu(dev->udev->descriptor.idProduct)) {
121780662d94SFrank Jungclaus 	case ESD_USB_CANUSB3_PRODUCT_ID:
121880662d94SFrank Jungclaus 		priv->can.clock.freq = ESD_USB_3_CAN_CLOCK;
121980662d94SFrank Jungclaus 		priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
122080662d94SFrank Jungclaus 		priv->can.bittiming_const = &esd_usb_3_nom_bittiming_const;
122180662d94SFrank Jungclaus 		priv->can.data_bittiming_const = &esd_usb_3_data_bittiming_const;
122280662d94SFrank Jungclaus 		priv->can.do_set_bittiming = esd_usb_3_set_bittiming;
122380662d94SFrank Jungclaus 		priv->can.do_set_data_bittiming = esd_usb_3_set_bittiming;
122480662d94SFrank Jungclaus 		break;
12255e910bdeSFrank Jungclaus 
122680662d94SFrank Jungclaus 	case ESD_USB_CANUSBM_PRODUCT_ID:
122780662d94SFrank Jungclaus 		priv->can.clock.freq = ESD_USB_M_CAN_CLOCK;
12288ef426e1SFrank Jungclaus 		priv->can.bittiming_const = &esd_usb_2_bittiming_const;
12298ef426e1SFrank Jungclaus 		priv->can.do_set_bittiming = esd_usb_2_set_bittiming;
123080662d94SFrank Jungclaus 		break;
123180662d94SFrank Jungclaus 
123280662d94SFrank Jungclaus 	case ESD_USB_CANUSB2_PRODUCT_ID:
123380662d94SFrank Jungclaus 	default:
123480662d94SFrank Jungclaus 		priv->can.clock.freq = ESD_USB_2_CAN_CLOCK;
123580662d94SFrank Jungclaus 		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
123680662d94SFrank Jungclaus 		priv->can.bittiming_const = &esd_usb_2_bittiming_const;
123780662d94SFrank Jungclaus 		priv->can.do_set_bittiming = esd_usb_2_set_bittiming;
123880662d94SFrank Jungclaus 		break;
123980662d94SFrank Jungclaus 	}
124080662d94SFrank Jungclaus 
12414d54977fSFrank Jungclaus 	priv->can.do_set_mode = esd_usb_set_mode;
12424d54977fSFrank Jungclaus 	priv->can.do_get_berr_counter = esd_usb_get_berr_counter;
12435e910bdeSFrank Jungclaus 
12445e910bdeSFrank Jungclaus 	netdev->flags |= IFF_ECHO; /* we support local echo */
12455e910bdeSFrank Jungclaus 
12464d54977fSFrank Jungclaus 	netdev->netdev_ops = &esd_usb_netdev_ops;
1247409c188cSVincent Mailhol 	netdev->ethtool_ops = &esd_usb_ethtool_ops;
12485e910bdeSFrank Jungclaus 
12495e910bdeSFrank Jungclaus 	SET_NETDEV_DEV(netdev, &intf->dev);
12505e910bdeSFrank Jungclaus 	netdev->dev_id = index;
12515e910bdeSFrank Jungclaus 
12525e910bdeSFrank Jungclaus 	err = register_candev(netdev);
12535e910bdeSFrank Jungclaus 	if (err) {
12545e910bdeSFrank Jungclaus 		dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
12555e910bdeSFrank Jungclaus 		free_candev(netdev);
12565e910bdeSFrank Jungclaus 		err = -ENOMEM;
12575e910bdeSFrank Jungclaus 		goto done;
12585e910bdeSFrank Jungclaus 	}
12595e910bdeSFrank Jungclaus 
12605e910bdeSFrank Jungclaus 	dev->nets[index] = priv;
12615e910bdeSFrank Jungclaus 	netdev_info(netdev, "device %s registered\n", netdev->name);
12625e910bdeSFrank Jungclaus 
12635e910bdeSFrank Jungclaus done:
12645e910bdeSFrank Jungclaus 	return err;
12655e910bdeSFrank Jungclaus }
12665e910bdeSFrank Jungclaus 
126722446100SFrank Jungclaus /* probe function for new USB devices
12685e910bdeSFrank Jungclaus  *
12695e910bdeSFrank Jungclaus  * check version information and number of available
12705e910bdeSFrank Jungclaus  * CAN interfaces
12715e910bdeSFrank Jungclaus  */
esd_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)12724d54977fSFrank Jungclaus static int esd_usb_probe(struct usb_interface *intf,
12735e910bdeSFrank Jungclaus 			 const struct usb_device_id *id)
12745e910bdeSFrank Jungclaus {
12754d54977fSFrank Jungclaus 	struct esd_usb *dev;
1276a57915aeSFrank Jungclaus 	union esd_usb_msg *msg;
12775e910bdeSFrank Jungclaus 	int i, err;
12785e910bdeSFrank Jungclaus 
12795e910bdeSFrank Jungclaus 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
12805e910bdeSFrank Jungclaus 	if (!dev) {
12815e910bdeSFrank Jungclaus 		err = -ENOMEM;
12825e910bdeSFrank Jungclaus 		goto done;
12835e910bdeSFrank Jungclaus 	}
12845e910bdeSFrank Jungclaus 
12855e910bdeSFrank Jungclaus 	dev->udev = interface_to_usbdev(intf);
12865e910bdeSFrank Jungclaus 
12875e910bdeSFrank Jungclaus 	init_usb_anchor(&dev->rx_submitted);
12885e910bdeSFrank Jungclaus 
12895e910bdeSFrank Jungclaus 	usb_set_intfdata(intf, dev);
12905e910bdeSFrank Jungclaus 
12915e910bdeSFrank Jungclaus 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
12925e910bdeSFrank Jungclaus 	if (!msg) {
12935e910bdeSFrank Jungclaus 		err = -ENOMEM;
12945e910bdeSFrank Jungclaus 		goto free_msg;
12955e910bdeSFrank Jungclaus 	}
12965e910bdeSFrank Jungclaus 
12975e910bdeSFrank Jungclaus 	/* query number of CAN interfaces (nets) */
12989dc3a695SFrank Jungclaus 	msg->hdr.cmd = ESD_USB_CMD_VERSION;
1299299a5576SFrank Jungclaus 	msg->hdr.len = sizeof(struct esd_usb_version_msg) / sizeof(u32); /* # of 32bit words */
1300a57915aeSFrank Jungclaus 	msg->version.rsvd = 0;
1301a57915aeSFrank Jungclaus 	msg->version.flags = 0;
1302a57915aeSFrank Jungclaus 	msg->version.drv_version = 0;
13035e910bdeSFrank Jungclaus 
13044d54977fSFrank Jungclaus 	err = esd_usb_send_msg(dev, msg);
13055e910bdeSFrank Jungclaus 	if (err < 0) {
13065e910bdeSFrank Jungclaus 		dev_err(&intf->dev, "sending version message failed\n");
13075e910bdeSFrank Jungclaus 		goto free_msg;
13085e910bdeSFrank Jungclaus 	}
13095e910bdeSFrank Jungclaus 
13104d54977fSFrank Jungclaus 	err = esd_usb_wait_msg(dev, msg);
13115e910bdeSFrank Jungclaus 	if (err < 0) {
13125e910bdeSFrank Jungclaus 		dev_err(&intf->dev, "no version message answer\n");
13135e910bdeSFrank Jungclaus 		goto free_msg;
13145e910bdeSFrank Jungclaus 	}
13155e910bdeSFrank Jungclaus 
1316a57915aeSFrank Jungclaus 	dev->net_count = (int)msg->version_reply.nets;
1317a57915aeSFrank Jungclaus 	dev->version = le32_to_cpu(msg->version_reply.version);
13185e910bdeSFrank Jungclaus 
13195e910bdeSFrank Jungclaus 	if (device_create_file(&intf->dev, &dev_attr_firmware))
13205e910bdeSFrank Jungclaus 		dev_err(&intf->dev,
13215e910bdeSFrank Jungclaus 			"Couldn't create device file for firmware\n");
13225e910bdeSFrank Jungclaus 
13235e910bdeSFrank Jungclaus 	if (device_create_file(&intf->dev, &dev_attr_hardware))
13245e910bdeSFrank Jungclaus 		dev_err(&intf->dev,
13255e910bdeSFrank Jungclaus 			"Couldn't create device file for hardware\n");
13265e910bdeSFrank Jungclaus 
13275e910bdeSFrank Jungclaus 	if (device_create_file(&intf->dev, &dev_attr_nets))
13285e910bdeSFrank Jungclaus 		dev_err(&intf->dev,
13295e910bdeSFrank Jungclaus 			"Couldn't create device file for nets\n");
13305e910bdeSFrank Jungclaus 
13315e910bdeSFrank Jungclaus 	/* do per device probing */
13325e910bdeSFrank Jungclaus 	for (i = 0; i < dev->net_count; i++)
13334d54977fSFrank Jungclaus 		esd_usb_probe_one_net(intf, i);
13345e910bdeSFrank Jungclaus 
13355e910bdeSFrank Jungclaus free_msg:
13365e910bdeSFrank Jungclaus 	kfree(msg);
13375e910bdeSFrank Jungclaus 	if (err)
13385e910bdeSFrank Jungclaus 		kfree(dev);
13395e910bdeSFrank Jungclaus done:
13405e910bdeSFrank Jungclaus 	return err;
13415e910bdeSFrank Jungclaus }
13425e910bdeSFrank Jungclaus 
134322446100SFrank Jungclaus /* called by the usb core when the device is removed from the system */
esd_usb_disconnect(struct usb_interface * intf)13444d54977fSFrank Jungclaus static void esd_usb_disconnect(struct usb_interface *intf)
13455e910bdeSFrank Jungclaus {
13464d54977fSFrank Jungclaus 	struct esd_usb *dev = usb_get_intfdata(intf);
13475e910bdeSFrank Jungclaus 	struct net_device *netdev;
13485e910bdeSFrank Jungclaus 	int i;
13495e910bdeSFrank Jungclaus 
13505e910bdeSFrank Jungclaus 	device_remove_file(&intf->dev, &dev_attr_firmware);
13515e910bdeSFrank Jungclaus 	device_remove_file(&intf->dev, &dev_attr_hardware);
13525e910bdeSFrank Jungclaus 	device_remove_file(&intf->dev, &dev_attr_nets);
13535e910bdeSFrank Jungclaus 
13545e910bdeSFrank Jungclaus 	usb_set_intfdata(intf, NULL);
13555e910bdeSFrank Jungclaus 
13565e910bdeSFrank Jungclaus 	if (dev) {
13575e910bdeSFrank Jungclaus 		for (i = 0; i < dev->net_count; i++) {
13585e910bdeSFrank Jungclaus 			if (dev->nets[i]) {
13595e910bdeSFrank Jungclaus 				netdev = dev->nets[i]->netdev;
13605e910bdeSFrank Jungclaus 				unregister_netdev(netdev);
13615e910bdeSFrank Jungclaus 				free_candev(netdev);
13625e910bdeSFrank Jungclaus 			}
13635e910bdeSFrank Jungclaus 		}
13645e910bdeSFrank Jungclaus 		unlink_all_urbs(dev);
13655e910bdeSFrank Jungclaus 		kfree(dev);
13665e910bdeSFrank Jungclaus 	}
13675e910bdeSFrank Jungclaus }
13685e910bdeSFrank Jungclaus 
13695e910bdeSFrank Jungclaus /* usb specific object needed to register this driver with the usb subsystem */
13704d54977fSFrank Jungclaus static struct usb_driver esd_usb_driver = {
13714741b3aeSVincent Mailhol 	.name = KBUILD_MODNAME,
13724d54977fSFrank Jungclaus 	.probe = esd_usb_probe,
13734d54977fSFrank Jungclaus 	.disconnect = esd_usb_disconnect,
13744d54977fSFrank Jungclaus 	.id_table = esd_usb_table,
13755e910bdeSFrank Jungclaus };
13765e910bdeSFrank Jungclaus 
13774d54977fSFrank Jungclaus module_usb_driver(esd_usb_driver);
1378