xref: /linux/drivers/net/can/usb/kvaser_usb/kvaser_usb.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
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>
257d102d0eSJimmy Assarsson #include <linux/ktime.h>
267d102d0eSJimmy Assarsson #include <linux/math64.h>
277259124eSJimmy Assarsson #include <linux/spinlock.h>
287259124eSJimmy Assarsson #include <linux/types.h>
297259124eSJimmy Assarsson #include <linux/usb.h>
307259124eSJimmy Assarsson #include <net/devlink.h>
317259124eSJimmy Assarsson 
327259124eSJimmy Assarsson #include <linux/can.h>
337259124eSJimmy Assarsson #include <linux/can/dev.h>
347259124eSJimmy Assarsson 
357259124eSJimmy Assarsson #define KVASER_USB_MAX_RX_URBS			4
367259124eSJimmy Assarsson #define KVASER_USB_MAX_TX_URBS			128
377259124eSJimmy Assarsson #define KVASER_USB_TIMEOUT			1000 /* msecs */
38aec5fb22SJimmy Assarsson #define KVASER_USB_RX_BUFFER_SIZE		3072
397259124eSJimmy Assarsson #define KVASER_USB_MAX_NET_DEVICES		5
4049f274c7SJimmy Assarsson 
4149f274c7SJimmy Assarsson /* Kvaser USB device quirks */
4249f274c7SJimmy Assarsson #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
43e6c80e60SJimmy Assarsson #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
447259124eSJimmy Assarsson #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
45aec5fb22SJimmy Assarsson 
46aec5fb22SJimmy Assarsson /* Device capabilities */
47aec5fb22SJimmy Assarsson #define KVASER_USB_CAP_BERR_CAP			0x01
48aec5fb22SJimmy Assarsson #define KVASER_USB_CAP_EXT_CAP			0x02
49aec5fb22SJimmy Assarsson #define KVASER_USB_HYDRA_CAP_EXT_CMD		0x04
507259124eSJimmy Assarsson 
517259124eSJimmy Assarsson #define KVASER_USB_SW_VERSION_MAJOR_MASK GENMASK(31, 24)
527259124eSJimmy Assarsson #define KVASER_USB_SW_VERSION_MINOR_MASK GENMASK(23, 16)
537259124eSJimmy Assarsson #define KVASER_USB_SW_VERSION_BUILD_MASK GENMASK(15, 0)
547259124eSJimmy Assarsson 
557259124eSJimmy Assarsson struct kvaser_usb_dev_cfg;
567259124eSJimmy Assarsson 
57aec5fb22SJimmy Assarsson enum kvaser_usb_leaf_family {
58aec5fb22SJimmy Assarsson 	KVASER_LEAF,
59aec5fb22SJimmy Assarsson 	KVASER_USBCAN,
60aec5fb22SJimmy Assarsson };
61aec5fb22SJimmy Assarsson 
62aec5fb22SJimmy Assarsson enum kvaser_usb_led_state {
63aec5fb22SJimmy Assarsson 	KVASER_USB_LED_ON = 0,
64aec5fb22SJimmy Assarsson 	KVASER_USB_LED_OFF = 1,
65aec5fb22SJimmy Assarsson };
66aec5fb22SJimmy Assarsson 
67aec5fb22SJimmy Assarsson #define KVASER_USB_HYDRA_MAX_CMD_LEN		128
687259124eSJimmy Assarsson struct kvaser_usb_dev_card_data_hydra {
697259124eSJimmy Assarsson 	u8 channel_to_he[KVASER_USB_MAX_NET_DEVICES];
70aec5fb22SJimmy Assarsson 	u8 sysdbg_he;
71aec5fb22SJimmy Assarsson 	spinlock_t transid_lock; /* lock for transid */
72c644c969SJimmy Assarsson 	u16 transid;
73aec5fb22SJimmy Assarsson 	/* lock for usb_rx_leftover and usb_rx_leftover_len */
747259124eSJimmy Assarsson 	spinlock_t usb_rx_leftover_lock;
757259124eSJimmy Assarsson 	u8 usb_rx_leftover[KVASER_USB_HYDRA_MAX_CMD_LEN];
767259124eSJimmy Assarsson 	u8 usb_rx_leftover_len;
777259124eSJimmy Assarsson };
787259124eSJimmy Assarsson struct kvaser_usb_dev_card_data {
797259124eSJimmy Assarsson 	u32 ctrlmode_supported;
807259124eSJimmy Assarsson 	u32 capabilities;
8100e57861SJimmy Assarsson 	struct kvaser_usb_dev_card_data_hydra hydra;
8200e57861SJimmy Assarsson 	u32 usbcan_timestamp_msb;
8300e57861SJimmy Assarsson };
8400e57861SJimmy Assarsson 
8500e57861SJimmy Assarsson /* Context for an outstanding, not yet ACKed, transmission */
8600e57861SJimmy Assarsson struct kvaser_usb_tx_urb_context {
8700e57861SJimmy Assarsson 	struct kvaser_usb_net_priv *priv;
8800e57861SJimmy Assarsson 	u32 echo_index;
897259124eSJimmy Assarsson };
907259124eSJimmy Assarsson 
917259124eSJimmy Assarsson struct kvaser_usb_fw_version {
927259124eSJimmy Assarsson 	u8 major;
9349f274c7SJimmy Assarsson 	u8 minor;
947259124eSJimmy Assarsson 	u16 build;
957259124eSJimmy Assarsson };
967259124eSJimmy Assarsson 
977259124eSJimmy Assarsson struct kvaser_usb_busparams {
987259124eSJimmy Assarsson 	__le32 bitrate;
997259124eSJimmy Assarsson 	u8 tseg1;
1007259124eSJimmy Assarsson 	u8 tseg2;
1017259124eSJimmy Assarsson 	u8 sjw;
1027259124eSJimmy Assarsson 	u8 nsamples;
1037259124eSJimmy Assarsson } __packed;
1047259124eSJimmy Assarsson 
1057259124eSJimmy Assarsson struct kvaser_usb {
1067259124eSJimmy Assarsson 	struct usb_device *udev;
1077259124eSJimmy Assarsson 	struct usb_interface *intf;
1087259124eSJimmy Assarsson 	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
1097259124eSJimmy Assarsson 	const struct kvaser_usb_driver_info *driver_info;
1107259124eSJimmy Assarsson 	const struct kvaser_usb_dev_cfg *cfg;
1117259124eSJimmy Assarsson 
1127259124eSJimmy Assarsson 	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
1137259124eSJimmy Assarsson 	struct usb_anchor rx_submitted;
1147259124eSJimmy Assarsson 
1157259124eSJimmy Assarsson 	u32 ean[2];
1167259124eSJimmy Assarsson 	u32 serial_number;
1178d21f592SAnssi Hannula 	struct kvaser_usb_fw_version fw_version;
1188d21f592SAnssi Hannula 	u8 hw_revision;
1198d21f592SAnssi Hannula 	unsigned int nchannels;
1207259124eSJimmy Assarsson 	/* @max_tx_urbs: Firmware-reported maximum number of outstanding,
1217259124eSJimmy Assarsson 	 * not yet ACKed, transmissions on this device. This value is
1227259124eSJimmy Assarsson 	 * also used as a sentinel for marking free tx contexts.
1237259124eSJimmy Assarsson 	 */
12439d3df6bSJimmy Assarsson 	unsigned int max_tx_urbs;
12539d3df6bSJimmy Assarsson 	struct kvaser_usb_dev_card_data card_data;
1267259124eSJimmy Assarsson 
1277259124eSJimmy Assarsson 	bool rxinitdone;
12839d3df6bSJimmy Assarsson 	void *rxbuf[KVASER_USB_MAX_RX_URBS];
12939d3df6bSJimmy Assarsson 	dma_addr_t rxbuf_dma[KVASER_USB_MAX_RX_URBS];
1307259124eSJimmy Assarsson };
1317259124eSJimmy Assarsson 
1327259124eSJimmy Assarsson struct kvaser_usb_net_priv {
1337259124eSJimmy Assarsson 	struct can_priv can;
1347259124eSJimmy Assarsson 	struct devlink_port devlink_port;
1357259124eSJimmy Assarsson 	struct can_berr_counter bec;
1367259124eSJimmy Assarsson 
1377259124eSJimmy Assarsson 	/* subdriver-specific data */
1387259124eSJimmy Assarsson 	void *sub_priv;
13939d3df6bSJimmy Assarsson 
140*b803c4a4SVincent Mailhol 	struct kvaser_usb *dev;
14139d3df6bSJimmy Assarsson 	struct net_device *netdev;
1427259124eSJimmy Assarsson 	int channel;
1437259124eSJimmy Assarsson 
1447259124eSJimmy Assarsson 	struct completion start_comp, stop_comp, flush_comp,
1457259124eSJimmy Assarsson 			  get_busparams_comp;
1468d21f592SAnssi Hannula 	struct usb_anchor tx_submitted;
1478d21f592SAnssi Hannula 
1487259124eSJimmy Assarsson 	struct kvaser_usb_busparams busparams_nominal, busparams_data;
149aec5fb22SJimmy Assarsson 
1507259124eSJimmy Assarsson 	spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
151aec5fb22SJimmy Assarsson 	int active_tx_contexts;
1527259124eSJimmy Assarsson 	struct kvaser_usb_tx_urb_context tx_contexts[];
1537259124eSJimmy Assarsson };
1547259124eSJimmy Assarsson 
1557259124eSJimmy Assarsson /**
1567259124eSJimmy Assarsson  * struct kvaser_usb_dev_ops - Device specific functions
1577259124eSJimmy Assarsson  * @dev_set_mode:		used for can.do_set_mode
1587259124eSJimmy Assarsson  * @dev_set_bittiming:		used for can.do_set_bittiming
1597259124eSJimmy Assarsson  * @dev_get_busparams:		readback arbitration busparams
1607259124eSJimmy Assarsson  * @dev_set_data_bittiming:	used for can.fd.do_set_data_bittiming
1617259124eSJimmy Assarsson  * @dev_get_data_busparams:	readback data busparams
1627259124eSJimmy Assarsson  * @dev_get_berr_counter:	used for can.do_get_berr_counter
16339d3df6bSJimmy Assarsson  *
16439d3df6bSJimmy Assarsson  * @dev_setup_endpoints:	setup USB in and out endpoints
16539d3df6bSJimmy Assarsson  * @dev_init_card:		initialize card
16639d3df6bSJimmy Assarsson  * @dev_init_channel:		initialize channel
16739d3df6bSJimmy Assarsson  * @dev_remove_channel:		uninitialize channel
16839d3df6bSJimmy Assarsson  * @dev_get_software_info:	get software info
1697259124eSJimmy Assarsson  * @dev_get_software_details:	get software details
1707259124eSJimmy Assarsson  * @dev_get_card_info:		get card info
1717259124eSJimmy Assarsson  * @dev_get_capabilities:	discover device capabilities
1727259124eSJimmy Assarsson  * @dev_set_led:		turn on/off device LED
1738d21f592SAnssi Hannula  *
1748d21f592SAnssi Hannula  * @dev_set_opt_mode:		set ctrlmod
1757259124eSJimmy Assarsson  * @dev_start_chip:		start the CAN controller
176aec5fb22SJimmy Assarsson  * @dev_stop_chip:		stop the CAN controller
1777259124eSJimmy Assarsson  * @dev_reset_chip:		reset the CAN controller
178aec5fb22SJimmy Assarsson  * @dev_flush_queue:		flush outstanding CAN messages
1797259124eSJimmy Assarsson  * @dev_read_bulk_callback:	handle incoming commands
1807259124eSJimmy Assarsson  * @dev_frame_to_cmd:		translate struct can_frame into device command
1817259124eSJimmy Assarsson  */
1827259124eSJimmy Assarsson struct kvaser_usb_dev_ops {
1837259124eSJimmy Assarsson 	int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
1847259124eSJimmy Assarsson 	int (*dev_set_bittiming)(const struct net_device *netdev,
1857259124eSJimmy Assarsson 				 const struct kvaser_usb_busparams *busparams);
1867259124eSJimmy Assarsson 	int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
187cc4b08c3SVincent Mailhol 	int (*dev_set_data_bittiming)(const struct net_device *netdev,
188cc4b08c3SVincent Mailhol 				      const struct kvaser_usb_busparams *busparams);
1897259124eSJimmy Assarsson 	int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
1907259124eSJimmy Assarsson 	int (*dev_get_berr_counter)(const struct net_device *netdev,
19149f274c7SJimmy Assarsson 				    struct can_berr_counter *bec);
19249f274c7SJimmy Assarsson 	int (*dev_setup_endpoints)(struct kvaser_usb *dev);
19349f274c7SJimmy Assarsson 	int (*dev_init_card)(struct kvaser_usb *dev);
19449f274c7SJimmy Assarsson 	int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
19549f274c7SJimmy Assarsson 	void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
19649f274c7SJimmy Assarsson 	int (*dev_get_software_info)(struct kvaser_usb *dev);
1977259124eSJimmy Assarsson 	int (*dev_get_software_details)(struct kvaser_usb *dev);
1987259124eSJimmy Assarsson 	int (*dev_get_card_info)(struct kvaser_usb *dev);
1997259124eSJimmy Assarsson 	int (*dev_get_capabilities)(struct kvaser_usb *dev);
2007259124eSJimmy Assarsson 	int (*dev_set_led)(struct kvaser_usb_net_priv *priv,
2017259124eSJimmy Assarsson 			   enum kvaser_usb_led_state state,
2027259124eSJimmy Assarsson 			   u16 duration_ms);
2037259124eSJimmy Assarsson 	int (*dev_set_opt_mode)(const struct kvaser_usb_net_priv *priv);
204aec5fb22SJimmy Assarsson 	int (*dev_start_chip)(struct kvaser_usb_net_priv *priv);
2057259124eSJimmy Assarsson 	int (*dev_stop_chip)(struct kvaser_usb_net_priv *priv);
2067259124eSJimmy Assarsson 	int (*dev_reset_chip)(struct kvaser_usb *dev, int channel);
207455561fbSAnssi Hannula 	int (*dev_flush_queue)(struct kvaser_usb_net_priv *priv);
208455561fbSAnssi Hannula 	void (*dev_read_bulk_callback)(struct kvaser_usb *dev, void *buf,
2097259124eSJimmy Assarsson 				       int len);
2107259124eSJimmy Assarsson 	void *(*dev_frame_to_cmd)(const struct kvaser_usb_net_priv *priv,
2117259124eSJimmy Assarsson 				  const struct sk_buff *skb, int *cmd_len,
2127259124eSJimmy Assarsson 				  u16 transid);
2137259124eSJimmy Assarsson };
2147259124eSJimmy Assarsson 
2157259124eSJimmy Assarsson struct kvaser_usb_driver_info {
2167259124eSJimmy Assarsson 	u32 quirks;
2177259124eSJimmy Assarsson 	enum kvaser_usb_leaf_family family;
21849f274c7SJimmy Assarsson 	const struct kvaser_usb_dev_ops *ops;
219b3b6df2cSJimmy Assarsson };
220b3b6df2cSJimmy Assarsson 
2217d102d0eSJimmy Assarsson struct kvaser_usb_dev_cfg {
2227d102d0eSJimmy Assarsson 	const struct can_clock clock;
2237d102d0eSJimmy Assarsson 	const unsigned int timestamp_freq;
2247d102d0eSJimmy Assarsson 	const struct can_bittiming_const * const bittiming_const;
2257d102d0eSJimmy Assarsson 	const struct can_bittiming_const * const data_bittiming_const;
2267d102d0eSJimmy Assarsson };
2277d102d0eSJimmy Assarsson 
2287d102d0eSJimmy Assarsson extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops;
2297d102d0eSJimmy Assarsson extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
2307d102d0eSJimmy Assarsson 
2317d102d0eSJimmy Assarsson extern const struct devlink_ops kvaser_usb_devlink_ops;
2327d102d0eSJimmy Assarsson 
2337d102d0eSJimmy Assarsson int kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv *priv);
2347d102d0eSJimmy Assarsson void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv);
2357d102d0eSJimmy Assarsson 
2367d102d0eSJimmy Assarsson void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv);
2377d102d0eSJimmy Assarsson 
2387d102d0eSJimmy Assarsson int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,
2397d102d0eSJimmy Assarsson 			int *actual_len);
2407d102d0eSJimmy Assarsson 
2417d102d0eSJimmy Assarsson int kvaser_usb_send_cmd(const struct kvaser_usb *dev, void *cmd, int len);
2427d102d0eSJimmy Assarsson 
2437259124eSJimmy Assarsson int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
244 			      int len);
245 
246 int kvaser_usb_can_rx_over_error(struct net_device *netdev);
247 
248 extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
249 
kvaser_usb_ticks_to_ktime(const struct kvaser_usb_dev_cfg * cfg,u64 ticks)250 static inline ktime_t kvaser_usb_ticks_to_ktime(const struct kvaser_usb_dev_cfg *cfg,
251 						u64 ticks)
252 {
253 	return ns_to_ktime(div_u64(ticks * 1000, cfg->timestamp_freq));
254 }
255 
kvaser_usb_timestamp48_to_ktime(const struct kvaser_usb_dev_cfg * cfg,const __le16 * timestamp)256 static inline ktime_t kvaser_usb_timestamp48_to_ktime(const struct kvaser_usb_dev_cfg *cfg,
257 						      const __le16 *timestamp)
258 {
259 	u64 ticks = le16_to_cpu(timestamp[0]) |
260 		    (u64)(le16_to_cpu(timestamp[1])) << 16 |
261 		    (u64)(le16_to_cpu(timestamp[2])) << 32;
262 
263 	return kvaser_usb_ticks_to_ktime(cfg, ticks);
264 }
265 
kvaser_usb_timestamp64_to_ktime(const struct kvaser_usb_dev_cfg * cfg,__le64 timestamp)266 static inline ktime_t kvaser_usb_timestamp64_to_ktime(const struct kvaser_usb_dev_cfg *cfg,
267 						      __le64 timestamp)
268 {
269 	return kvaser_usb_ticks_to_ktime(cfg, le64_to_cpu(timestamp));
270 }
271 
272 #endif /* KVASER_USB_H */
273