Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7259124e authored by Jimmy Assarsson's avatar Jimmy Assarsson Committed by Marc Kleine-Budde
Browse files

can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c



First part of adding support for Kvaser USB device family "hydra".

Split kvaser_usb.c into kvaser_usb/kvaser_usb{.h,_core.c,_leaf.c}.

kvaser_usb_core.c contains common functionality, such as USB
writing/reading and allocation of netdev.
kvaser_usb_leaf.c contains device specific code, used in
kvaser_usb_core.c.

struct kvaser_usb_dev_ops contains device specific functions that are
common for all devices in the family. While, struct kvaser_usb_dev_cfg
describes the device configurations in terms of CAN clock frequency,
timestamp frequency and CAN controller bittiming constants.

Signed-off-by: default avatarJimmy Assarsson <extja@kvaser.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent e0543f24
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o
obj-$(CONFIG_CAN_GS_USB) += gs_usb.o
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb/
obj-$(CONFIG_CAN_MCBA_USB) += mcba_usb.o
obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/
obj-$(CONFIG_CAN_UCAN) += ucan.o
+2 −0
Original line number Diff line number Diff line
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
kvaser_usb-y = kvaser_usb_core.o kvaser_usb_leaf.o
+158 −0
Original line number Diff line number Diff line
/* 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)
 *
 * 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 two major families:
 * - Leaf: Based on Renesas M32C, 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		3

/* USB devices features */
#define KVASER_USB_HAS_SILENT_MODE		BIT(0)
#define KVASER_USB_HAS_TXRX_ERRORS		BIT(1)

struct kvaser_usb_dev_cfg;

enum kvaser_usb_leaf_family {
	KVASER_LEAF,
	KVASER_USBCAN,
};

struct kvaser_usb_dev_card_data {
	u32 ctrlmode_supported;
	struct {
		enum kvaser_usb_leaf_family family;
	} leaf;
};

/* 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 {
	struct usb_device *udev;
	struct usb_interface *intf;
	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
	const struct kvaser_usb_dev_ops *ops;
	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;

	struct kvaser_usb *dev;
	struct net_device *netdev;
	int channel;

	struct completion start_comp, stop_comp;
	struct usb_anchor tx_submitted;

	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_berr_counter:	used for can.do_get_berr_counter
 *
 * @dev_setup_endpoints:	setup USB in and out endpoints
 * @dev_init_card:		initialize card
 * @dev_get_software_info:	get software info
 * @dev_get_card_info:		get card info
 *
 * @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)(struct net_device *netdev);
	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_get_software_info)(struct kvaser_usb *dev);
	int (*dev_get_card_info)(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_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_leaf_dev_ops;

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);
#endif /* KVASER_USB_H */
+769 −0

File added.

Preview size limit exceeded, changes collapsed.

+1363 −0

File changed and moved.

Preview size limit exceeded, changes collapsed.

Loading