diff options
Diffstat (limited to 'drivers/net/can/usb/kvaser_usb/kvaser_usb.h')
-rw-r--r-- | drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h new file mode 100644 index 000000000..5699531f8 --- /dev/null +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Parts of this driver are based on the following: + * - Kvaser linux leaf driver (version 4.78) + * - CAN driver for esd CAN-USB/2 + * - Kvaser linux usbcanII driver (version 5.3) + * - Kvaser linux mhydra driver (version 5.24) + * + * Copyright (C) 2002-2018 KVASER AB, Sweden. All rights reserved. + * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh + * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be> + * Copyright (C) 2015 Valeo S.A. + */ + +#ifndef KVASER_USB_H +#define KVASER_USB_H + +/* Kvaser USB CAN dongles are divided into three major platforms: + * - Hydra: Running firmware labeled as 'mhydra' + * - Leaf: Based on Renesas M32C or Freescale i.MX28, running firmware labeled + * as 'filo' + * - UsbcanII: Based on Renesas M16C, running firmware labeled as 'helios' + */ + +#include <linux/completion.h> +#include <linux/spinlock.h> +#include <linux/types.h> +#include <linux/usb.h> + +#include <linux/can.h> +#include <linux/can/dev.h> + +#define KVASER_USB_MAX_RX_URBS 4 +#define KVASER_USB_MAX_TX_URBS 128 +#define KVASER_USB_TIMEOUT 1000 /* msecs */ +#define KVASER_USB_RX_BUFFER_SIZE 3072 +#define KVASER_USB_MAX_NET_DEVICES 5 + +/* Kvaser USB device quirks */ +#define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) +#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) +#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2) + +/* Device capabilities */ +#define KVASER_USB_CAP_BERR_CAP 0x01 +#define KVASER_USB_CAP_EXT_CAP 0x02 +#define KVASER_USB_HYDRA_CAP_EXT_CMD 0x04 + +struct kvaser_usb_dev_cfg; + +enum kvaser_usb_leaf_family { + KVASER_LEAF, + KVASER_USBCAN, +}; + +#define KVASER_USB_HYDRA_MAX_CMD_LEN 128 +struct kvaser_usb_dev_card_data_hydra { + u8 channel_to_he[KVASER_USB_MAX_NET_DEVICES]; + u8 sysdbg_he; + spinlock_t transid_lock; /* lock for transid */ + u16 transid; + /* lock for usb_rx_leftover and usb_rx_leftover_len */ + spinlock_t usb_rx_leftover_lock; + u8 usb_rx_leftover[KVASER_USB_HYDRA_MAX_CMD_LEN]; + u8 usb_rx_leftover_len; +}; +struct kvaser_usb_dev_card_data { + u32 ctrlmode_supported; + u32 capabilities; + struct kvaser_usb_dev_card_data_hydra hydra; +}; + +/* Context for an outstanding, not yet ACKed, transmission */ +struct kvaser_usb_tx_urb_context { + struct kvaser_usb_net_priv *priv; + u32 echo_index; + int dlc; +}; + +struct kvaser_usb_busparams { + __le32 bitrate; + u8 tseg1; + u8 tseg2; + u8 sjw; + u8 nsamples; +} __packed; + +struct kvaser_usb { + struct usb_device *udev; + struct usb_interface *intf; + struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES]; + const struct kvaser_usb_driver_info *driver_info; + const struct kvaser_usb_dev_cfg *cfg; + + struct usb_endpoint_descriptor *bulk_in, *bulk_out; + struct usb_anchor rx_submitted; + + /* @max_tx_urbs: Firmware-reported maximum number of outstanding, + * not yet ACKed, transmissions on this device. This value is + * also used as a sentinel for marking free tx contexts. + */ + u32 fw_version; + unsigned int nchannels; + unsigned int max_tx_urbs; + struct kvaser_usb_dev_card_data card_data; + + bool rxinitdone; + void *rxbuf[KVASER_USB_MAX_RX_URBS]; + dma_addr_t rxbuf_dma[KVASER_USB_MAX_RX_URBS]; +}; + +struct kvaser_usb_net_priv { + struct can_priv can; + struct can_berr_counter bec; + + /* subdriver-specific data */ + void *sub_priv; + + struct kvaser_usb *dev; + struct net_device *netdev; + int channel; + + struct completion start_comp, stop_comp, flush_comp, + get_busparams_comp; + struct usb_anchor tx_submitted; + + struct kvaser_usb_busparams busparams_nominal, busparams_data; + + spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */ + int active_tx_contexts; + struct kvaser_usb_tx_urb_context tx_contexts[]; +}; + +/** + * struct kvaser_usb_dev_ops - Device specific functions + * @dev_set_mode: used for can.do_set_mode + * @dev_set_bittiming: used for can.do_set_bittiming + * @dev_get_busparams: readback arbitration busparams + * @dev_set_data_bittiming: used for can.do_set_data_bittiming + * @dev_get_data_busparams: readback data busparams + * @dev_get_berr_counter: used for can.do_get_berr_counter + * + * @dev_setup_endpoints: setup USB in and out endpoints + * @dev_init_card: initialize card + * @dev_init_channel: initialize channel + * @dev_remove_channel: uninitialize channel + * @dev_get_software_info: get software info + * @dev_get_software_details: get software details + * @dev_get_card_info: get card info + * @dev_get_capabilities: discover device capabilities + * + * @dev_set_opt_mode: set ctrlmod + * @dev_start_chip: start the CAN controller + * @dev_stop_chip: stop the CAN controller + * @dev_reset_chip: reset the CAN controller + * @dev_flush_queue: flush outstanding CAN messages + * @dev_read_bulk_callback: handle incoming commands + * @dev_frame_to_cmd: translate struct can_frame into device command + */ +struct kvaser_usb_dev_ops { + int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode); + int (*dev_set_bittiming)(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams); + int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv); + int (*dev_set_data_bittiming)(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams); + int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv); + int (*dev_get_berr_counter)(const struct net_device *netdev, + struct can_berr_counter *bec); + int (*dev_setup_endpoints)(struct kvaser_usb *dev); + int (*dev_init_card)(struct kvaser_usb *dev); + int (*dev_init_channel)(struct kvaser_usb_net_priv *priv); + void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv); + int (*dev_get_software_info)(struct kvaser_usb *dev); + int (*dev_get_software_details)(struct kvaser_usb *dev); + int (*dev_get_card_info)(struct kvaser_usb *dev); + int (*dev_get_capabilities)(struct kvaser_usb *dev); + int (*dev_set_opt_mode)(const struct kvaser_usb_net_priv *priv); + int (*dev_start_chip)(struct kvaser_usb_net_priv *priv); + int (*dev_stop_chip)(struct kvaser_usb_net_priv *priv); + int (*dev_reset_chip)(struct kvaser_usb *dev, int channel); + int (*dev_flush_queue)(struct kvaser_usb_net_priv *priv); + void (*dev_read_bulk_callback)(struct kvaser_usb *dev, void *buf, + int len); + void *(*dev_frame_to_cmd)(const struct kvaser_usb_net_priv *priv, + const struct sk_buff *skb, int *frame_len, + int *cmd_len, u16 transid); +}; + +struct kvaser_usb_driver_info { + u32 quirks; + enum kvaser_usb_leaf_family family; + const struct kvaser_usb_dev_ops *ops; +}; + +struct kvaser_usb_dev_cfg { + const struct can_clock clock; + const unsigned int timestamp_freq; + const struct can_bittiming_const * const bittiming_const; + const struct can_bittiming_const * const data_bittiming_const; +}; + +extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; +extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; + +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); + +int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, + int *actual_len); + +int kvaser_usb_send_cmd(const struct kvaser_usb *dev, void *cmd, int len); + +int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd, + int len); + +int kvaser_usb_can_rx_over_error(struct net_device *netdev); + +extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const; + +#endif /* KVASER_USB_H */ |