#ifndef KVASER_USB_H
#define KVASER_USB_H
#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
#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)
#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP BIT(3)
#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;
u16 transid;
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;
};
struct kvaser_usb_tx_urb_context {
struct kvaser_usb_net_priv *priv;
u32 echo_index;
};
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;
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;
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;
int active_tx_contexts;
struct kvaser_usb_tx_urb_context tx_contexts[];
};
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 *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 */