17259124eSJimmy Assarsson /* SPDX-License-Identifier: GPL-2.0 */
27259124eSJimmy Assarsson /* Parts of this driver are based on the following:
37259124eSJimmy Assarsson  *  - Kvaser linux leaf driver (version 4.78)
47259124eSJimmy Assarsson  *  - CAN driver for esd CAN-USB/2
57259124eSJimmy Assarsson  *  - Kvaser linux usbcanII driver (version 5.3)
6aec5fb22SJimmy Assarsson  *  - Kvaser linux mhydra driver (version 5.24)
77259124eSJimmy Assarsson  *
87259124eSJimmy Assarsson  * Copyright (C) 2002-2018 KVASER AB, Sweden. All rights reserved.
97259124eSJimmy Assarsson  * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
107259124eSJimmy Assarsson  * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be>
117259124eSJimmy Assarsson  * Copyright (C) 2015 Valeo S.A.
127259124eSJimmy Assarsson  */
137259124eSJimmy Assarsson 
147259124eSJimmy Assarsson #ifndef KVASER_USB_H
157259124eSJimmy Assarsson #define KVASER_USB_H
167259124eSJimmy Assarsson 
17aec5fb22SJimmy Assarsson /* Kvaser USB CAN dongles are divided into three major platforms:
18aec5fb22SJimmy Assarsson  * - Hydra: Running firmware labeled as 'mhydra'
19aec5fb22SJimmy Assarsson  * - Leaf: Based on Renesas M32C or Freescale i.MX28, running firmware labeled
20aec5fb22SJimmy Assarsson  *         as 'filo'
217259124eSJimmy Assarsson  * - UsbcanII: Based on Renesas M16C, running firmware labeled as 'helios'
227259124eSJimmy Assarsson  */
237259124eSJimmy Assarsson 
247259124eSJimmy Assarsson #include <linux/completion.h>
257259124eSJimmy Assarsson #include <linux/spinlock.h>
267259124eSJimmy Assarsson #include <linux/types.h>
277259124eSJimmy Assarsson #include <linux/usb.h>
287259124eSJimmy Assarsson 
297259124eSJimmy Assarsson #include <linux/can.h>
307259124eSJimmy Assarsson #include <linux/can/dev.h>
317259124eSJimmy Assarsson 
327259124eSJimmy Assarsson #define KVASER_USB_MAX_RX_URBS			4
337259124eSJimmy Assarsson #define KVASER_USB_MAX_TX_URBS			128
347259124eSJimmy Assarsson #define KVASER_USB_TIMEOUT			1000 /* msecs */
357259124eSJimmy Assarsson #define KVASER_USB_RX_BUFFER_SIZE		3072
36aec5fb22SJimmy Assarsson #define KVASER_USB_MAX_NET_DEVICES		5
377259124eSJimmy Assarsson 
3849f274c7SJimmy Assarsson /* Kvaser USB device quirks */
3949f274c7SJimmy Assarsson #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
4049f274c7SJimmy Assarsson #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
41e6c80e60SJimmy Assarsson #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
421d5eeda2SVincent Mailhol #define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP	BIT(3)
437259124eSJimmy Assarsson 
44aec5fb22SJimmy Assarsson /* Device capabilities */
45aec5fb22SJimmy Assarsson #define KVASER_USB_CAP_BERR_CAP			0x01
46aec5fb22SJimmy Assarsson #define KVASER_USB_CAP_EXT_CAP			0x02
47aec5fb22SJimmy Assarsson #define KVASER_USB_HYDRA_CAP_EXT_CMD		0x04
48aec5fb22SJimmy Assarsson 
497259124eSJimmy Assarsson struct kvaser_usb_dev_cfg;
507259124eSJimmy Assarsson 
517259124eSJimmy Assarsson enum kvaser_usb_leaf_family {
527259124eSJimmy Assarsson 	KVASER_LEAF,
537259124eSJimmy Assarsson 	KVASER_USBCAN,
547259124eSJimmy Assarsson };
557259124eSJimmy Assarsson 
56aec5fb22SJimmy Assarsson #define KVASER_USB_HYDRA_MAX_CMD_LEN		128
57aec5fb22SJimmy Assarsson struct kvaser_usb_dev_card_data_hydra {
58aec5fb22SJimmy Assarsson 	u8 channel_to_he[KVASER_USB_MAX_NET_DEVICES];
59aec5fb22SJimmy Assarsson 	u8 sysdbg_he;
60aec5fb22SJimmy Assarsson 	spinlock_t transid_lock; /* lock for transid */
61aec5fb22SJimmy Assarsson 	u16 transid;
62aec5fb22SJimmy Assarsson 	/* lock for usb_rx_leftover and usb_rx_leftover_len */
63aec5fb22SJimmy Assarsson 	spinlock_t usb_rx_leftover_lock;
64aec5fb22SJimmy Assarsson 	u8 usb_rx_leftover[KVASER_USB_HYDRA_MAX_CMD_LEN];
65aec5fb22SJimmy Assarsson 	u8 usb_rx_leftover_len;
66aec5fb22SJimmy Assarsson };
677259124eSJimmy Assarsson struct kvaser_usb_dev_card_data {
687259124eSJimmy Assarsson 	u32 ctrlmode_supported;
69aec5fb22SJimmy Assarsson 	u32 capabilities;
70aec5fb22SJimmy Assarsson 	struct kvaser_usb_dev_card_data_hydra hydra;
71aec5fb22SJimmy Assarsson };
727259124eSJimmy Assarsson 
737259124eSJimmy Assarsson /* Context for an outstanding, not yet ACKed, transmission */
747259124eSJimmy Assarsson struct kvaser_usb_tx_urb_context {
757259124eSJimmy Assarsson 	struct kvaser_usb_net_priv *priv;
767259124eSJimmy Assarsson 	u32 echo_index;
777259124eSJimmy Assarsson };
787259124eSJimmy Assarsson 
7900e57861SJimmy Assarsson struct kvaser_usb_busparams {
8000e57861SJimmy Assarsson 	__le32 bitrate;
8100e57861SJimmy Assarsson 	u8 tseg1;
8200e57861SJimmy Assarsson 	u8 tseg2;
8300e57861SJimmy Assarsson 	u8 sjw;
8400e57861SJimmy Assarsson 	u8 nsamples;
8500e57861SJimmy Assarsson } __packed;
8600e57861SJimmy Assarsson 
877259124eSJimmy Assarsson struct kvaser_usb {
887259124eSJimmy Assarsson 	struct usb_device *udev;
897259124eSJimmy Assarsson 	struct usb_interface *intf;
907259124eSJimmy Assarsson 	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
9149f274c7SJimmy Assarsson 	const struct kvaser_usb_driver_info *driver_info;
927259124eSJimmy Assarsson 	const struct kvaser_usb_dev_cfg *cfg;
937259124eSJimmy Assarsson 
947259124eSJimmy Assarsson 	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
957259124eSJimmy Assarsson 	struct usb_anchor rx_submitted;
967259124eSJimmy Assarsson 
977259124eSJimmy Assarsson 	/* @max_tx_urbs: Firmware-reported maximum number of outstanding,
987259124eSJimmy Assarsson 	 * not yet ACKed, transmissions on this device. This value is
997259124eSJimmy Assarsson 	 * also used as a sentinel for marking free tx contexts.
1007259124eSJimmy Assarsson 	 */
1017259124eSJimmy Assarsson 	u32 fw_version;
1027259124eSJimmy Assarsson 	unsigned int nchannels;
1037259124eSJimmy Assarsson 	unsigned int max_tx_urbs;
1047259124eSJimmy Assarsson 	struct kvaser_usb_dev_card_data card_data;
1057259124eSJimmy Assarsson 
1067259124eSJimmy Assarsson 	bool rxinitdone;
1077259124eSJimmy Assarsson 	void *rxbuf[KVASER_USB_MAX_RX_URBS];
1087259124eSJimmy Assarsson 	dma_addr_t rxbuf_dma[KVASER_USB_MAX_RX_URBS];
1097259124eSJimmy Assarsson };
1107259124eSJimmy Assarsson 
1117259124eSJimmy Assarsson struct kvaser_usb_net_priv {
1127259124eSJimmy Assarsson 	struct can_priv can;
1137259124eSJimmy Assarsson 	struct can_berr_counter bec;
1147259124eSJimmy Assarsson 
1158d21f592SAnssi Hannula 	/* subdriver-specific data */
1168d21f592SAnssi Hannula 	void *sub_priv;
1178d21f592SAnssi Hannula 
1187259124eSJimmy Assarsson 	struct kvaser_usb *dev;
1197259124eSJimmy Assarsson 	struct net_device *netdev;
1207259124eSJimmy Assarsson 	int channel;
1217259124eSJimmy Assarsson 
122*39d3df6bSJimmy Assarsson 	struct completion start_comp, stop_comp, flush_comp,
123*39d3df6bSJimmy Assarsson 			  get_busparams_comp;
1247259124eSJimmy Assarsson 	struct usb_anchor tx_submitted;
1257259124eSJimmy Assarsson 
126*39d3df6bSJimmy Assarsson 	struct kvaser_usb_busparams busparams_nominal, busparams_data;
127*39d3df6bSJimmy Assarsson 
1287259124eSJimmy Assarsson 	spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
1297259124eSJimmy Assarsson 	int active_tx_contexts;
1307259124eSJimmy Assarsson 	struct kvaser_usb_tx_urb_context tx_contexts[];
1317259124eSJimmy Assarsson };
1327259124eSJimmy Assarsson 
1337259124eSJimmy Assarsson /**
1347259124eSJimmy Assarsson  * struct kvaser_usb_dev_ops - Device specific functions
1357259124eSJimmy Assarsson  * @dev_set_mode:		used for can.do_set_mode
1367259124eSJimmy Assarsson  * @dev_set_bittiming:		used for can.do_set_bittiming
137*39d3df6bSJimmy Assarsson  * @dev_get_busparams:		readback arbitration busparams
138aec5fb22SJimmy Assarsson  * @dev_set_data_bittiming:	used for can.do_set_data_bittiming
139*39d3df6bSJimmy Assarsson  * @dev_get_data_busparams:	readback data busparams
1407259124eSJimmy Assarsson  * @dev_get_berr_counter:	used for can.do_get_berr_counter
1417259124eSJimmy Assarsson  *
1427259124eSJimmy Assarsson  * @dev_setup_endpoints:	setup USB in and out endpoints
1437259124eSJimmy Assarsson  * @dev_init_card:		initialize card
1448d21f592SAnssi Hannula  * @dev_init_channel:		initialize channel
1458d21f592SAnssi Hannula  * @dev_remove_channel:		uninitialize channel
1467259124eSJimmy Assarsson  * @dev_get_software_info:	get software info
147aec5fb22SJimmy Assarsson  * @dev_get_software_details:	get software details
1487259124eSJimmy Assarsson  * @dev_get_card_info:		get card info
149aec5fb22SJimmy Assarsson  * @dev_get_capabilities:	discover device capabilities
1507259124eSJimmy Assarsson  *
1517259124eSJimmy Assarsson  * @dev_set_opt_mode:		set ctrlmod
1527259124eSJimmy Assarsson  * @dev_start_chip:		start the CAN controller
1537259124eSJimmy Assarsson  * @dev_stop_chip:		stop the CAN controller
1547259124eSJimmy Assarsson  * @dev_reset_chip:		reset the CAN controller
1557259124eSJimmy Assarsson  * @dev_flush_queue:		flush outstanding CAN messages
1567259124eSJimmy Assarsson  * @dev_read_bulk_callback:	handle incoming commands
1577259124eSJimmy Assarsson  * @dev_frame_to_cmd:		translate struct can_frame into device command
1587259124eSJimmy Assarsson  */
1597259124eSJimmy Assarsson struct kvaser_usb_dev_ops {
1607259124eSJimmy Assarsson 	int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
161*39d3df6bSJimmy Assarsson 	int (*dev_set_bittiming)(const struct net_device *netdev,
162*39d3df6bSJimmy Assarsson 				 const struct kvaser_usb_busparams *busparams);
163*39d3df6bSJimmy Assarsson 	int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
164*39d3df6bSJimmy Assarsson 	int (*dev_set_data_bittiming)(const struct net_device *netdev,
165*39d3df6bSJimmy Assarsson 				      const struct kvaser_usb_busparams *busparams);
166*39d3df6bSJimmy Assarsson 	int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
1677259124eSJimmy Assarsson 	int (*dev_get_berr_counter)(const struct net_device *netdev,
1687259124eSJimmy Assarsson 				    struct can_berr_counter *bec);
1697259124eSJimmy Assarsson 	int (*dev_setup_endpoints)(struct kvaser_usb *dev);
1707259124eSJimmy Assarsson 	int (*dev_init_card)(struct kvaser_usb *dev);
1718d21f592SAnssi Hannula 	int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
1728d21f592SAnssi Hannula 	void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
1737259124eSJimmy Assarsson 	int (*dev_get_software_info)(struct kvaser_usb *dev);
174aec5fb22SJimmy Assarsson 	int (*dev_get_software_details)(struct kvaser_usb *dev);
1757259124eSJimmy Assarsson 	int (*dev_get_card_info)(struct kvaser_usb *dev);
176aec5fb22SJimmy Assarsson 	int (*dev_get_capabilities)(struct kvaser_usb *dev);
1777259124eSJimmy Assarsson 	int (*dev_set_opt_mode)(const struct kvaser_usb_net_priv *priv);
1787259124eSJimmy Assarsson 	int (*dev_start_chip)(struct kvaser_usb_net_priv *priv);
1797259124eSJimmy Assarsson 	int (*dev_stop_chip)(struct kvaser_usb_net_priv *priv);
1807259124eSJimmy Assarsson 	int (*dev_reset_chip)(struct kvaser_usb *dev, int channel);
1817259124eSJimmy Assarsson 	int (*dev_flush_queue)(struct kvaser_usb_net_priv *priv);
1827259124eSJimmy Assarsson 	void (*dev_read_bulk_callback)(struct kvaser_usb *dev, void *buf,
1837259124eSJimmy Assarsson 				       int len);
1847259124eSJimmy Assarsson 	void *(*dev_frame_to_cmd)(const struct kvaser_usb_net_priv *priv,
185cc4b08c3SVincent Mailhol 				  const struct sk_buff *skb, int *cmd_len,
186cc4b08c3SVincent Mailhol 				  u16 transid);
1877259124eSJimmy Assarsson };
1887259124eSJimmy Assarsson 
18949f274c7SJimmy Assarsson struct kvaser_usb_driver_info {
19049f274c7SJimmy Assarsson 	u32 quirks;
19149f274c7SJimmy Assarsson 	enum kvaser_usb_leaf_family family;
19249f274c7SJimmy Assarsson 	const struct kvaser_usb_dev_ops *ops;
19349f274c7SJimmy Assarsson };
19449f274c7SJimmy Assarsson 
1957259124eSJimmy Assarsson struct kvaser_usb_dev_cfg {
1967259124eSJimmy Assarsson 	const struct can_clock clock;
1977259124eSJimmy Assarsson 	const unsigned int timestamp_freq;
1987259124eSJimmy Assarsson 	const struct can_bittiming_const * const bittiming_const;
1997259124eSJimmy Assarsson 	const struct can_bittiming_const * const data_bittiming_const;
2007259124eSJimmy Assarsson };
2017259124eSJimmy Assarsson 
202aec5fb22SJimmy Assarsson extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops;
2037259124eSJimmy Assarsson extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
2047259124eSJimmy Assarsson 
205455561fbSAnssi Hannula void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv);
206455561fbSAnssi Hannula 
2077259124eSJimmy Assarsson int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,
2087259124eSJimmy Assarsson 			int *actual_len);
2097259124eSJimmy Assarsson 
2107259124eSJimmy Assarsson int kvaser_usb_send_cmd(const struct kvaser_usb *dev, void *cmd, int len);
2117259124eSJimmy Assarsson 
2127259124eSJimmy Assarsson int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
2137259124eSJimmy Assarsson 			      int len);
2147259124eSJimmy Assarsson 
2157259124eSJimmy Assarsson int kvaser_usb_can_rx_over_error(struct net_device *netdev);
21649f274c7SJimmy Assarsson 
217b3b6df2cSJimmy Assarsson extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
218b3b6df2cSJimmy Assarsson 
2197259124eSJimmy Assarsson #endif /* KVASER_USB_H */
220