[PATCH 1/4] can: usb: ixxat_usb: add shared header

Stéphane Grosjean <[email protected]> Thu, 23 Jul 2026 09:29:36 +0200
Newsgroups org.kernel.vger.linux-can
Message-ID <[email protected]>
From: Stéphane Grosjean <[email protected]>

Add ixxat_usb_core.h, which defines the data structures, constants and
USB wire-protocol layouts shared by all three IXXAT USB communication
layers (CL1, CL2 and CAN IDM).

Included in this header:
  - USB vendor and product IDs for all supported devices
  - On-wire message structures for CL1 and CL2 (ixxat_can_msg_cl1,
    ixxat_can_msg_cl2) including the 64-byte CAN FD payload variant
  - Command/response structures for device init, start, stop, reset,
    bittiming (ixxat_canbtp), capabilities (ixxat_cancaps2) and
    firmware version queries
  - Per-channel runtime state (struct ixxat_usb_candevice) and per-adapter
    descriptor (struct ixxat_usb_adapter) with bittiming constants,
    supported control modes and USB endpoint layout

Signed-off-by: Stéphane Grosjean <[email protected]>
---
 .../net/can/usb/ixxat_usb/ixxat_usb_core.h    | 862 ++++++++++++++++++
 1 file changed, 862 insertions(+)
 create mode 100644 drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h

diff --git a/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h
new file mode 100644
index 000000000000..62799d8040b1
--- /dev/null
+++ b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h
@@ -0,0 +1,862 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* CAN driver base for IXXAT USB-to-CAN
+ *
+ * Copyright (C) 2018-2024 HMS Industrial Networks <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef IXXAT_USB_CORE_H
+#define IXXAT_USB_CORE_H
+
+/* vendor ids used by IXXAT devices */
+#define IXXAT_USB_VENDOR_ID_LEGACY		0x08d8
+#define IXXAT_USB_VENDOR_ID			0x08db
+
+/* supported device ids: CL1 */
+#define USB2CAN_V2_COMPACT_PRODUCT_ID		0x0008
+#define USB2CAN_V2_EMBEDDED_PRODUCT_ID		0x0009
+#define USB2CAN_V2_PROFESSIONAL_PRODUCT_ID	0x000A
+#define USB2CAN_V2_AUTOMOTIVE_PRODUCT_ID	0x000B
+#define USB2CAN_V2_PLUGIN_PRODUCT_ID		0x001F
+
+/* supported device ids: CL2 */
+#define USB2CAN_FD_COMPACT_PRODUCT_ID		0x0014
+#define USB2CAN_FD_EMBEDDED_PRODUCT_ID		0x0015
+#define USB2CAN_FD_AUTOMOTIVE_PRODUCT_ID	0x0017
+#define USB2CAN_FD_PCIE_MINI_PRODUCT_ID		0x001B
+#define USB2CAR_PRODUCT_ID			0x001C
+#define CAN_IDM101_PRODUCT_ID			0xFF12
+#define CAN_IDM200_PRODUCT_ID			0xFF13
+
+/* supported device ids: CL2 */
+#define USB2CAN_FD_PRO_PRODUCT_ID		0x0010
+#define USB2CAN_FD_STANDARD_PRODUCT_ID		0x0011
+#define USB2CAN_FD_STANDARD_CARD_PRODUCT_ID	0x0012
+#define USB2CAN_FD_PRO_MODULE_PRODUCT_ID	0x0013
+#define USB2CAN_FD_STANDARD_MODULE_PRODUCT_ID	0x0014
+
+#define IXXAT_USB_BUS_CAN			1
+
+#define IXXAT_USB_BUS_TYPE(type)		((u8)(((type) >> 8) & 0x00FF))
+
+#define IXXAT_USB_STATE_CONNECTED		BIT(0)
+#define IXXAT_USB_STATE_STARTED			BIT(1)
+
+#define IXXAT_USB_FREE_ENTRY			0xFFFF
+
+#define IXXAT_USB_MAX_CHANNEL			5
+#define IXXAT_USB_MAX_TYPES			32
+#define IXXAT_USB_MAX_RX_URBS			4
+#define IXXAT_USB_MAX_TX_URBS			10
+
+#define IXXAT_USB_DEV_FWTYPE_BAL		3	/* BAL conform FW */
+#define IXXAT_USB_DEV_FWTYPE_BMG		4	/* BMG conform FW */
+
+#define IXXAT_USB_OPMODE_STANDARD		BIT(0)
+#define IXXAT_USB_OPMODE_EXTENDED		BIT(1)
+#define IXXAT_USB_OPMODE_ERRFRAME		BIT(2)
+#define IXXAT_USB_OPMODE_LISTONLY		BIT(3)
+
+#define IXXAT_USB_EXMODE_EXTDATA		BIT(0)
+#define IXXAT_USB_EXMODE_FASTDATA		BIT(1)
+#define IXXAT_USB_EXMODE_ISOFD			BIT(2)
+
+#define IXXAT_USB_BTMODE_NAT			BIT(0)
+#define IXXAT_USB_BTMODE_TSM			BIT(1)
+
+#define IXXAT_USB_STOP_ACTION_CLEARALL		3
+
+/* ctrltype values are split into upper/lower half:
+ * Bit 15..8 : bus type (0 is reserved)
+ * Bit  7..0 : controller type
+ */
+#define IXXAT_USB_BUSTYPE_RES			0
+#define IXXAT_USB_BUSTYPE_CAN			1
+#define IXXAT_USB_BUSTYPE_LIN			2
+
+#define IXXAT_USB_GET_BUSTYPE(ctrltype)		(((ctrltype) >> 8) & 0x00FF)
+#define IXXAT_USB_GET_CTRLTYPE(ctrltype)	((ctrltype) & 0x00FF)
+
+#define IXXAT_USB_CAN_CTRL_UNKNOWN		0x00 /* unknown CAN controller */
+#define IXXAT_USB_CAN_CTRL_INTEL_82527		0x01
+#define IXXAT_USB_CAN_CTRL_INTEL_82C200		0x02
+#define IXXAT_USB_CAN_CTRL_INTEL_81C90		0x03
+#define IXXAT_USB_CAN_CTRL_INTEL_81C92		0x04
+#define IXXAT_USB_CAN_CTRL_PHILIPS_SJA1000	0x05
+#define IXXAT_USB_CAN_CTRL_INFINEON_82C900	0x06 /* TwinCAN */
+#define IXXAT_USB_CAN_CTRL_MOTOROLA_TOUCAN	0x07
+#define IXXAT_USB_CAN_CTRL_FREESCALE_STAR12_MSCAN	0x08
+#define IXXAT_USB_CAN_CTRL_FREESCALE_COLDFIRE_FLEXCAN	0x09
+#define IXXAT_USB_CAN_CTRL_IFI_CAN		0x0A /* IFI-CAN ( ALTERA FPGA CAN ) */
+#define IXXAT_USB_CAN_CTRL_BOSCH_CCAN		0x0B /* CCAN ( Bosch C_CAN ) */
+#define IXXAT_USB_CAN_CTRL_ST_BXCAN		0x0C /* ST BX_CAN */
+#define IXXAT_USB_CAN_CTRL_IFI_CANFD		0x0D /* IFI-CANFD ( ALTERA FPGA CAN ) */
+#define IXXAT_USB_CAN_CTRL_MCAN			0x0E /* MCAN (Bosch M_CAN version A) */
+
+/*
+ * Values up to 0x3F are reserved for CAN-only and legacy CAN FD
+ * controllers. The values for new CAN FD controllers are in the
+ * range from 0x40 to 0x7F. The values in the range from 0x80 to
+ * 0xFF are reserved for future extensions.
+ */
+
+#define IXXAT_USB_CAN_CTRL_GENERIC_CANFD	0x40 /* generic CAN FD controller */
+#define IXXAT_USB_CAN_CTRL_IFI_CANFD2		0x41 /* IFI-CANFD */
+#define IXXAT_USB_CAN_CTRL_BOSCH_MCAN_VERSION_B	0x42 /* MCAN (Bosch M_CAN version B) */
+
+/* CAN controller feature flags */
+#define IXXAT_USB_CAN_FEATURE_STDOREXT		0x00000001  /* 11 OR 29 bit (exclusive) */
+#define IXXAT_USB_CAN_FEATURE_STDANDEXT		0x00000002  /* 11 AND 29 bit (simultaneous) */
+#define IXXAT_USB_CAN_FEATURE_RMTFRAME		0x00000004  /* reception of remote frames */
+#define IXXAT_USB_CAN_FEATURE_ERRFRAME		0x00000008  /* reception of error frames */
+#define IXXAT_USB_CAN_FEATURE_BUSLOAD		0x00000010  /* bus load measurement */
+#define IXXAT_USB_CAN_FEATURE_IDFILTER		0x00000020  /* exact message filter */
+#define IXXAT_USB_CAN_FEATURE_LISTONLY		0x00000040  /* listen only mode */
+#define IXXAT_USB_CAN_FEATURE_SCHEDULER		0x00000080  /* cyclic message scheduler */
+#define IXXAT_USB_CAN_FEATURE_GENERRFRM		0x00000100  /* error frame generation */
+#define IXXAT_USB_CAN_FEATURE_DELAYEDTX		0x00000200  /* delayed message transmitter */
+#define IXXAT_USB_CAN_FEATURE_SSM		0x00000400  /* single shot mode */
+#define IXXAT_USB_CAN_FEATURE_HI_PRIO		0x00000800  /* high priority message */
+
+#define IXXAT_USB_CAN_FEATURE_EXTDATA		0x00001000  /* extended data length (CAN FD) */
+#define IXXAT_USB_CAN_FEATURE_FASTDATA		0x00002000  /* fast data bit rate (CAN FD) */
+
+#define IXXAT_USB_CAN_FEATURE_CLRTX		0x00004000  /* single tx try msg with ack error */
+
+#define IXXAT_USB_CAN_FEATURE_ISOFD		0x00008000  /* i: ISO CAN FD */
+#define IXXAT_USB_CAN_FEATURE_NONISOFD		0x00010000  /* i: non-ISO CAN FD */
+
+#define IXXAT_USB_CAN_FEATURE_AUTOBAUD		0x00020000  /* automatic bit rate detection */
+
+#define IXXAT_USB_CAN_FEATURE_TXSELFACK		0x00040000  /* transmit self acknowledge */
+#define IXXAT_USB_CAN_FEATURE_TXDELAYSEL	0x00080000  /* transmit delay mode selection */
+
+#define IXXAT_USB_CAN_BUSC_UNDEFINED		0x0000
+#define IXXAT_USB_CAN_BUSC_LOWSPEED		0x0001
+#define IXXAT_USB_CAN_BUSC_HIGHSPEED		0x0002
+
+#define IXXAT_USB_CAN_DATA			0x00
+#define IXXAT_USB_CAN_INFO			0x01
+#define IXXAT_USB_CAN_ERROR			0x02
+#define IXXAT_USB_CAN_STATUS			0x03
+#define IXXAT_USB_CAN_WAKEUP			0x04
+#define IXXAT_USB_CAN_TIMEOVR			0x05
+#define IXXAT_USB_CAN_TIMERST			0x06
+
+#define IXXAT_USB_CAN_STATUS_OK			0x00000000
+#define IXXAT_USB_CAN_STATUS_OVERRUN		0x00000002
+#define IXXAT_USB_CAN_STATUS_ERRLIM		0x00000004
+#define IXXAT_USB_CAN_STATUS_BUSOFF		0x00000008
+#define IXXAT_USB_CAN_STATUS_ERR_PAS		0x00002000
+
+#define IXXAT_USB_CAN_ERROR_LEN			5
+
+#define IXXAT_USB_CAN_ERROR_CODE		0
+#define IXXAT_USB_CAN_ERROR_COUNTER_RX		3
+#define IXXAT_USB_CAN_ERROR_COUNTER_TX		4
+
+#define IXXAT_USB_CAN_ERROR_STUFF		1
+#define IXXAT_USB_CAN_ERROR_FORM		2
+#define IXXAT_USB_CAN_ERROR_ACK			3
+#define IXXAT_USB_CAN_ERROR_BIT			4
+#define IXXAT_USB_CAN_ERROR_CRC			6
+
+#define IXXAT_USB_MSG_FLAGS_TYPE		0x000000FF
+#define IXXAT_USB_MSG_FLAGS_DLC			0x000F0000
+#define IXXAT_USB_MSG_FLAGS_OVR			0x00100000
+#define IXXAT_USB_MSG_FLAGS_SRR			0x00200000
+#define IXXAT_USB_MSG_FLAGS_RTR			0x00400000
+#define IXXAT_USB_MSG_FLAGS_EXT			0x00800000
+
+#define IXXAT_USB_DECODE_DLC(flags)		\
+				(((flags) & IXXAT_USB_MSG_FLAGS_DLC) >> 16)
+
+#define IXXAT_USB_ENCODE_DLC(len)		\
+				(((len) << 16) & IXXAT_USB_MSG_FLAGS_DLC)
+
+#define IXXAT_USB_MSG_FLAGS_SINGLESHOT		0x00000100
+#define IXXAT_USB_MSG_FLAGS_HIPRIORITY		0x00000200
+
+#define IXXAT_USB_MSG_FLAGS_TXDELAYMODE		0x00002000
+#define IXXAT_USB_MSG_FLAGS_TXDELAYMODE_PRE	0x00000000
+#define IXXAT_USB_MSG_FLAGS_TXDELAYMODE_POST	IXXAT_USB_MSG_FLAGS_TXDELAYMODE
+
+#define IXXAT_USB_FDMSG_FLAGS_EDL		0x00000400
+#define IXXAT_USB_FDMSG_FLAGS_FDR		0x00000800
+#define IXXAT_USB_FDMSG_FLAGS_ESI		0x00001000
+
+/* USB command timeout values  */
+/* for IXXAT_USB_BRD_CMD_POWER (wakeup/sleep) */
+#define IXXAT_USB_POWER_CMD_TIMEOUT		500
+
+/* for other commands */
+#define IXXAT_USB_CMD_TIMEOUT			100
+
+/* port/socket index to address board functionality */
+#define IXXAT_USB_BRD_PORT			0xffff
+#define IXXAT_USB_BRD_SOCKET			0xffff
+
+/* CAN related commands*/
+#define IXXAT_USB_CAN_CMD_START			0x326
+#define IXXAT_USB_CAN_CMD_STOP			0x327
+#define IXXAT_USB_CAN_CMD_RESET			0x328
+
+/* board related commands */
+#define IXXAT_USB_BRD_CMD_GET_FWINFO		0x400
+#define IXXAT_USB_BRD_CMD_GET_DEVCAPS		0x401
+#define IXXAT_USB_BRD_CMD_GET_DEVINFO		0x402
+#define IXXAT_USB_BRD_CMD_GET_FWINFO2		0x403
+#define IXXAT_USB_BRD_CMD_POWER			0x421
+
+/* struct ixxat_can_msg_base - IXXAT CAN message base (CL1/CL2)
+ * @size: Message size (this field excluded)
+ * @time: Message timestamp
+ * @msg_id: Message ID
+ * @flags: Message flags
+ *
+ * Contains the common fields of an IXXAT CAN message on both CL1 and CL2
+ * devices
+ */
+struct ixxat_can_msg_base {
+	u8 size;
+	__le32 time;
+	__le32 msg_id;
+	__le32 flags;
+} __packed;
+
+/* struct ixxat_can_msg_cl1 - IXXAT CAN message (CL1)
+ * @data: Message data (standard CAN frame)
+ *
+ * Contains the fields of an IXXAT CAN message on CL1 devices
+ */
+struct ixxat_can_msg_cl1 {
+	u8 data[CAN_MAX_DLEN];
+} __packed;
+
+/* struct ixxat_can_msg_cl2 - IXXAT CAN message (CL2)
+ * @client_id: Client ID
+ * @data: Message data (CAN FD frame)
+ *
+ * Contains the fields of an IXXAT CAN message on CL2 devices
+ */
+struct ixxat_can_msg_cl2 {
+	__le32 client_id;
+	u8 data[CANFD_MAX_DLEN];
+} __packed;
+
+/* struct ixxat_can_msg - IXXAT CAN message
+ * @base: Base message
+ * @cl1: Cl1 message
+ * @cl2: Cl2 message
+ *
+ * Contains an IXXAT CAN message
+ */
+struct ixxat_can_msg {
+	struct ixxat_can_msg_base base;
+	union {
+		struct ixxat_can_msg_cl1 cl1;
+		struct ixxat_can_msg_cl2 cl2;
+	};
+} __packed;
+
+/* struct ixxat_dev_caps - Device capabilities
+ * @bus_ctrl_count: Stores the bus controller counter
+ * @bus_ctrl_types: Stores the bus controller types
+ *
+ * Contains the device capabilities
+ */
+struct ixxat_dev_caps {
+	__le16 bus_ctrl_count;
+	__le16 bus_ctrl_types[IXXAT_USB_MAX_TYPES];
+} __packed;
+
+/* struct ixxat_canbtp Bittiming parameters (CL2)
+ * @mode: Operation mode
+ * @bps: Bits per second
+ * @ts1: First time segment
+ * @ts2: Second time segment
+ * @sjw: Synchronization jump width
+ * @tdo: Transmitter delay offset
+ *
+ * Bittiming parameters of a CL2 initialization request
+ */
+struct ixxat_canbtp {
+	__le32 mode;
+	__le32 bps;
+	__le16 ts1;
+	__le16 ts2;
+	__le16 sjw;
+	__le16 tdo;
+} __packed;
+
+/* struct ixxat_dev_info IXXAT USB device information
+ * @device_name: Name of the device
+ * @device_id: Device identification (unique device id)
+ * @device_version: Device version (0, 1, ...)
+ * @device_fpga_version: Version of FPGA design
+ *
+ * Contains device information of IXXAT USB devices
+ */
+struct ixxat_dev_info {
+	char device_name[16];
+	char device_id[16];
+	__le16 device_version;
+	__le32 device_fpga_version;
+} __packed;
+
+/* struct ixxat_fw_info IXXAT USB device firmware information
+ * @firmware_type: type of currently running firmware
+ * @major_version: major firmware version number
+ * @minor_version: minor firmware version number
+ * @build_version: build firmware version number
+ *
+ * Contains device information of IXXAT USB devices
+ */
+struct ixxat_fw_info {
+	__le32 firmware_type;
+	__le16 res;
+	__le16 major_version;
+	__le16 minor_version;
+	__le16 build_version;
+} __packed;
+
+/* struct ixxat_fw_info2 IXXAT USB device firmware information
+ * @firmware_type: type of currently running firmware
+ * @major_version: major firmware version number
+ * @minor_version: minor firmware version number
+ * @build_version: build firmware version number
+ * @revision     : revision number
+ *
+ * Contains device information of IXXAT USB devices
+ */
+struct ixxat_fw_info2 {
+	__le32 firmware_type;
+	__le16 res;
+	__le16 major_version;
+	__le16 minor_version;
+	__le16 build_version;
+	__le16 revision;
+} __packed;
+
+/* struct ixxat_cancaps CAN controller capabilities
+ * ctrltype;		Type of CAN controller (see IXXAT_USB_CAN_CTRL_ const)
+ * buscoupling;		Type of Bus coupling (see IXXAT_USB_CAN_BUSC_ const)
+ * features;		supported features (see IXXAT_USB_CAN_FEATURE_ constants)
+ * can_clock_freq:	clock frequency of the primary counter in Hz
+ * ts_clock_divisor:	divisor for the message time stamp counter
+ * cms_clock_divisor:	divisor for the cyclic message scheduler
+ * cms_max_ticks:	maximum tick count value of the cyclic message
+ *			scheduler
+ * dtx_clock_divisor:	divisor for the delayed message transmitter
+ * dtx_max_ticks:	maximum tick count value of the delayed
+ *			message transmitter
+ *
+ * Contains CAN controller capabilities information
+ */
+struct ixxat_cancaps {
+	__le16 ctrltype;
+	__le16 buscoupling;
+	__le32 features;
+	__le32 can_clock_freq;
+	__le32 ts_clock_divisor;
+	__le32 cms_clock_divisor;
+	__le32 cms_max_ticks;
+	__le32 dtx_clock_divisor;
+	__le32 dtx_max_ticks;
+} __packed;
+
+/* struct ixxat_cancaps2 CANFD controller capabilities
+ * ctrltype;		Type of CAN controller (see IXXAT_USB_CAN_CTRL_ const)
+ * buscoupling;		Type of Bus coupling (see IXXAT_USB_CAN_BUSC_ const)
+ * features;		supported features (see IXXAT_USB_CAN_FEATURE_ constants)
+ * can_clock_freq:	CAN clock frequency in Hz (16/2 MHz for SJA1000)
+ * sdr_range_min;	minimum bit timing values for standard bit rate
+ * sdr_range_max;	maximum bit timing values for standard bit rate
+ * fdr_range_min;	minimum bit timing values for fast data bit rate
+ * fdr_range_max;	maximum bit timing values for fast data bit rate
+ * ts_clock_freq;	clock frequency of the time stamp counter [Hz]
+ * ts_clock_divisor;	divisor for the message time stamp counter
+ * cms_clock_freq;	clock frequency of cyclic message scheduler [Hz]
+ * cms_clock_divisor;	divisor for the cyclic message scheduler
+ * cms_max_ticks;	maximum tick count value of the cyclic message
+ *			scheduler
+ * dtx_clock_freq;	clock frequency of the delayed message transmitter [Hz]
+ * dtx_clock_divisor;	divisor for the delayed message transmitter
+ * dtx_max_ticks;	maximum tick count value of the delayed
+ *			message transmitter
+ *
+ * Contains CANFD controller capabilities information
+ */
+struct ixxat_cancaps2 {
+	__le16 ctrltype;
+	__le16 buscoupling;
+	__le32 features;
+	__le32 can_clock_freq;
+	struct ixxat_canbtp sdr_range_min;
+	struct ixxat_canbtp sdr_range_max;
+	struct ixxat_canbtp fdr_range_min;
+	struct ixxat_canbtp fdr_range_max;
+	__le32 ts_clock_freq;
+	__le32 ts_clock_divisor;
+	__le32 cms_clock_freq;
+	__le32 cms_clock_divisor;
+	__le32 cms_max_ticks;
+	__le32 dtx_clock_freq;
+	__le32 dtx_clock_divisor;
+	__le32 dtx_max_ticks;
+} __packed;
+
+/* Device timestamps
+ *
+ * Every device maintains an internal clock used for message timestamps.
+ * The resolution of the clock is reported by the controller capabilities and
+ * denotes the resolution of one clock tick by the two values:
+ * ts_clock_freq/ts_clock_divisor
+ * The following timeline occurs during the operation of a controller:
+ *
+ *         t_start                                      t_stop
+ *     <------------>                               <------------>
+ *
+ *     A            B           D                   E            F          H
+ *     |            |           |                   |            |          |
+ *     v            v           v                   v            v          v
+ *  ---------------------------------~  ...  ~----------------------------------> t
+ *           ^                                            ^
+ *           |                                            |
+ *           C                                            G
+ *
+ * A: controller start command (request) is sent to the device
+ * B: controller start command (response) returns from device and returns device
+ *    time stamp of C
+ * C: assumed CAN controller start time stamp, it is assumed to be in the middle
+ *     between A and B (A + (t_start/2))
+ * D: controller start info message arrives over the message fifo, it contains
+ *    the device time stamp of C, too
+ * E: controller stop command (request) is sent to the device
+ * F: controller stop command (response) returns
+ * G: assumed CAN controller stop time stamp, it is assumed to be in the middle
+ *    between E and F (E + (t_stop/2))
+ * H: controller stop info message arrives over the message fifo, it contains
+ *    the device time stamp of G
+ *
+ * To correlate the start timestamp to the host clock we determine:
+ *
+ *     t_host_C = (t_host_B + t_host_A) / 2
+ *              = t_host_A + ((t_host_A - t_host_B) / 2)
+ *
+ * t_C_host then corresponds to the device clock tick at C (t_C_device).
+ * The current time stamp correlated to the host clock (t_current_host) can then
+ * be determined via
+ *
+ *     t_host_current = t_host_C + conv_to_nsec(t_dev_current - t_dev_C)
+ *
+ * struct ixxat_time_ref Time reference
+ * tick_multiplier:	used to convert ticks to ns
+ * tick_divider:	used to convert ticks to ns
+ * @ts_overrun_ticks:	number of timer overruns since start
+ *
+ * Contains time references of the device and the host
+ */
+struct ixxat_time_ref {
+	u64 tick_multiplier;
+	u64 tick_divider;
+	u64 ts_overrun_ticks;
+};
+
+/* struct ixxat_tx_urb_context URB content for transmission
+ * @dev: pointer to the IXXAT USB CAN device
+ * @urb: USB request block
+ * @urb_index: index of this URB (used to mark the context as occupied)
+ * @msg_index: index of message (client_id)
+ * @msg_packet_len: Data length code (only used if no loopback is enabled)
+ * @msg_packet_no: number of packets (only used if no loopback is enabled)
+ *
+ * Contains content for USB request block transmissions
+ */
+struct ixxat_tx_urb_context {
+	struct ixxat_usb_candevice *dev;
+	struct urb *urb;
+	u16  urb_index;
+	u16  msg_index;
+};
+
+/* struct ixxat_usb_candevice IXXAT USB CAN device
+ * @can: CAN common private data
+ * @adapter: USB network descriptor
+ * @udev: USB device
+ * @netdev: Net_device
+ * @active_tx_urbs: Active tx urbs
+ * @tx_anchor: Submitted tx USB anchor
+ * @tx_contexts: Buffer for tx contexts
+ * @rx_anchor: Submitted rx USB anchor
+ * @msgs: store to set the used message indexes
+ * @msg_lastindex: last index which was set
+ * @loopback:  global loopback
+ * @state: Device state
+ * @ctrl_index: Controller index
+ * @ep_msg_in: USB endpoint for incoming messages
+ * @ep_msg_out: USB endpoint for outgoing messages
+ * @prev_dev: Previous opened device
+ * @time_ref: Time reference
+ * @dev_info: Device information
+ * @bec: CAN error counter
+ *
+ * IXXAT USB based CAN device
+ */
+struct ixxat_usb_candevice {
+	struct can_priv can;
+	const struct ixxat_usb_adapter *adapter;
+	struct usb_device *udev;
+	struct net_device *netdev;
+
+	atomic_t active_tx_urbs;
+	struct usb_anchor tx_anchor;
+	struct ixxat_tx_urb_context tx_contexts[IXXAT_USB_MAX_TX_URBS];
+
+	struct usb_anchor rx_anchor;
+	void  *rx_buf[IXXAT_USB_MAX_RX_URBS];
+
+	u32 msgs;
+	u32 msg_lastindex;
+
+	bool loopback;
+	u32 state;
+	u16 ctrl_index;
+
+	u8 ep_msg_in;
+	u8 ep_msg_out;
+
+	/* This lock prevents a race condition between xmit and receive. */
+	spinlock_t dev_lock;
+
+	/* pointer to shared USB device data  */
+	struct ixxat_usb_device_data *shareddata;
+
+	/* used to link can devices together */
+	struct ixxat_usb_candevice *prev_dev;
+
+	struct ixxat_time_ref time_ref;
+
+	struct can_berr_counter bec;
+};
+
+/* struct ixxat_usb_dal_req IXXAT device request block
+ * @size: Request size
+ * @port: Request port
+ * @socket: Request socket
+ * @code: Request code
+ *
+ * IXXAT device request block
+ */
+struct ixxat_usb_dal_req {
+	__le32 size;
+	__le16 port;
+	__le16 socket;
+	__le32 code;
+} __packed;
+
+/* struct ixxat_usb_dal_res IXXAT device response block
+ * @res_size: Expected response size
+ * @ret_size: Actual response size
+ * @code: Return code
+ *
+ * IXXAT device response block
+ */
+struct ixxat_usb_dal_res {
+	__le32 res_size;
+	__le32 ret_size;
+	__le32 code;
+} __packed;
+
+/* struct ixxat_usb_dal_cmd IXXAT device command
+ * @req: Request block
+ * @req: Response block
+ *
+ * IXXAT device command
+ */
+struct ixxat_usb_dal_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+} __packed;
+
+/* struct ixxat_usb_caps_cmd Device capabilities command
+ * @req: Request block
+ * @res: Response block
+ * @caps: Device capabilities
+ *
+ * Can be sent to a device to request its capabilities
+ */
+struct ixxat_usb_caps_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_dev_caps caps;
+	__le16 rsvd;
+} __packed;
+
+/* struct ixxat_usb_init_cl1_cmd Initialization command (CL1)
+ * @req: Request block
+ * @mode: Operation mode
+ * @btr0: Bittiming register 0
+ * @btr1: Bittiming register 1
+ * @padding: 1 byte padding
+ * @res: Response block
+ *
+ * Can be sent to a CL1 device to initialize it
+ */
+struct ixxat_usb_init_cl1_cmd {
+	struct ixxat_usb_dal_req req;
+	u8 mode;
+	u8 btr0;
+	u8 btr1;
+	u8 padding;
+	struct ixxat_usb_dal_res res;
+} __packed;
+
+/* struct ixxat_usb_init_cl2_cmd Initialization command (CL2)
+ * @req: Request block
+ * @opmode: Operation mode
+ * @exmode: Extended mode
+ * @sdr: Standard bittiming parameters
+ * @fdr: Fast data bittiming parameters
+ * @_padding: 2 bytes padding
+ * @res: Response block
+ *
+ * Can be sent to a CL2 device to initialize it
+ */
+struct ixxat_usb_init_cl2_cmd {
+	struct ixxat_usb_dal_req req;
+	u8 opmode;
+	u8 exmode;
+	struct ixxat_canbtp sdr;
+	struct ixxat_canbtp fdr;
+	__le16 _padding;
+	struct ixxat_usb_dal_res res;
+} __packed;
+
+/* struct ixxat_usb_getcaps_cl1_cmd Controller read capabilities
+ * @req: Request block
+ * @res: Response block
+ * @caps: Controller capabilities
+ *
+ * Can be sent to a device to get the controller capabilities
+ */
+struct ixxat_usb_getcaps_cl1_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_cancaps caps;
+} __packed;
+
+/* struct ixxat_usb_getcaps_cl2_cmd Controller read capabilities
+ * @req: Request block
+ * @res: Response block
+ * @caps: Controller capabilities
+ *
+ * Can be sent to a device to get the controller capabilities
+ */
+struct ixxat_usb_getcaps_cl2_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_cancaps2 caps;
+} __packed;
+
+/* struct ixxat_usb_start_cmd Controller start command
+ * @req: Request block
+ * @res: Response block
+ * @time: Timestamp
+ *
+ * Can be sent to a device to start its controller
+ */
+struct ixxat_usb_start_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	__le32 time;
+} __packed;
+
+/* struct ixxat_usb_stop_cmd Controller stop command
+ * @req: Request block
+ * @action: Stop action
+ * @res: Response block
+ *
+ * Can be sent to a device to start its controller
+ */
+struct ixxat_usb_stop_cmd {
+	struct ixxat_usb_dal_req req;
+	__le32 action;
+	struct ixxat_usb_dal_res res;
+} __packed;
+
+/* struct ixxat_usb_power_cmd Power command
+ * @req: Request block
+ * @mode: Power mode
+ * @_padding1: 1 byte padding
+ * @_padding2: 2 byte padding
+ * @res: Response block
+ *
+ * Can be sent to a device to set its power mode
+ */
+struct ixxat_usb_power_cmd {
+	struct ixxat_usb_dal_req req;
+	u8 mode;
+	u8 _padding1;
+	__le16 _padding2;
+	struct ixxat_usb_dal_res res;
+} __packed;
+
+/* struct ixxat_usb_info_cmd Device information command
+ * @req: Request block
+ * @res: Response block
+ * @info: Device information
+ *
+ * Can be sent to a device to request its device information
+ */
+struct ixxat_usb_info_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_dev_info info;
+	__le16 rsvd;
+} __packed;
+
+/* struct ixxat_usb_fwinfo_cmd Firmware information command
+ * @req: Request block
+ * @res: Response block
+ * @info: Firmware information
+ *
+ * Can be sent to a device to request its firmware information
+ */
+struct ixxat_usb_fwinfo_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_fw_info info;
+} __packed;
+
+/* struct ixxat_usb_fwinfo2_cmd Firmware information command
+ * @req: Request block
+ * @res: Response block
+ * @info: Firmware information
+ *
+ * Can be sent to a device to request its firmware information
+ */
+struct ixxat_usb_fwinfo2_cmd {
+	struct ixxat_usb_dal_req req;
+	struct ixxat_usb_dal_res res;
+	struct ixxat_fw_info2 info;
+} __packed;
+
+/* USB command buffer */
+union ixxat_usb_cmd {
+	struct ixxat_usb_caps_cmd caps;
+	struct ixxat_usb_info_cmd info;
+	struct ixxat_usb_fwinfo_cmd fwinfo;
+	struct ixxat_usb_fwinfo2_cmd fwinfo2;
+	struct ixxat_usb_start_cmd start;
+	struct ixxat_usb_stop_cmd stop;
+	struct ixxat_usb_power_cmd power;
+	struct ixxat_usb_dal_cmd dal;
+
+	struct ixxat_usb_init_cl1_cmd cl1;
+	struct ixxat_usb_getcaps_cl1_cmd caps_cl1;
+
+	struct ixxat_usb_init_cl2_cmd cl2;
+	struct ixxat_usb_getcaps_cl2_cmd caps_cl2;
+};
+
+/* struct ixxat_usb_device_data IXXAT USB device data
+ * @timeref_valid: Time reference valid
+ * @kt_host_start: Host start time
+ * @ts_dev_start: Device start time
+ */
+struct ixxat_usb_device_data {
+	/* used to lock write access to the device members */
+	spinlock_t access_lock;
+
+	/* lock access to command channel on endpoint 0 */
+	struct mutex cmd_channel_lock;
+
+	/* device and firmware info */
+	struct ixxat_dev_info dev_info;
+	struct ixxat_fw_info2 fw_info;
+
+	/* controller capabilities */
+	struct ixxat_cancaps2 caps;
+
+	/* time reference of first controller start */
+	bool    timeref_valid;
+	ktime_t kt_host_start;
+	u32     ts_dev_start;
+
+	/* USB commands buffer */
+	union ixxat_usb_cmd *cmdbuf;
+};
+
+/* struct ixxat_usb_adapter IXXAT USB device adapter
+ * @clock: Clock frequency
+ * @bt: Bittiming constants
+ * @btd: Data bittiming constants
+ * @modes: Supported modes
+ * @buffer_size_rx: Buffer size for receiving
+ * @buffer_size_tx: Buffer size for transfer
+ * @ep_msg_in: USB endpoint buffer for incoming messages
+ * @ep_msg_out: USB endpoint buffer for outgoing messages
+ * @ep_offs: Endpoint offset (device depended)
+ *
+ * Device Adapter for IXXAT USB devices
+ */
+struct ixxat_usb_adapter {
+	const u32 modes;
+	const u32 clock;
+	const struct can_bittiming_const *bt;
+	const struct can_bittiming_const *btd;
+	const u16 buffer_size_rx;
+	const u16 buffer_size_tx;
+	const u8 ep_msg_in[IXXAT_USB_MAX_CHANNEL];
+	const u8 ep_msg_out[IXXAT_USB_MAX_CHANNEL];
+	const u8 ep_offs;
+
+	int (*get_ctrl_caps)(struct ixxat_usb_candevice *dev,
+			     struct ixxat_cancaps2 *caps);
+	int (*init_ctrl)(struct ixxat_usb_candevice *dev);
+};
+
+extern const struct ixxat_usb_adapter usb2can_cl1;
+extern const struct ixxat_usb_adapter usb2can_v2;
+extern const struct ixxat_usb_adapter usb2can_fd;
+extern const struct ixxat_usb_adapter can_fd_idm;
+
+/* ixxat_usb_setup_cmd() - Setup a device command
+ * @req: Request block
+ * @res: Response block
+ *
+ * This function sets the default values in the request and the response block
+ * of a device command
+ */
+void ixxat_usb_setup_cmd(struct ixxat_usb_dal_req *req,
+			 struct ixxat_usb_dal_res *res);
+
+/* ixxat_usb_send_cmd() - Send a command to the device
+ * @dev: pointer to the IXXAT USB CAN device
+ * @dev: pointer to the USB device
+ * @devdata: pointer to the IXXAT USB device data
+ * @port: port number to send the command to
+ * @req: pointer to the request structure
+ * @req_size: size of the request structure
+ * @res: pointer to the response structure
+ * @res_size: size of the response structure
+ * @cmd_delay: delay in milliseconds to wait for a response
+ *
+ * This function sends a specific command to the device
+ *
+ * Return: Negative error code or zero on success
+ */
+int ixxat_usb_send_cmd(struct ixxat_usb_candevice *dev, const u16 port,
+		       void *req, const u16 req_size, void *res,
+		       const u16 res_size, const unsigned long cmd_delay);
+
+#endif /* IXXAT_USB_CORE_H */
-- 
2.53.0