linux/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c

// SPDX-License-Identifier: GPL-2.0
/* Parts of this driver are based on the following:
 *  - Kvaser linux mhydra driver (version 5.24)
 *  - CAN driver for esd CAN-USB/2
 *
 * Copyright (C) 2018 KVASER AB, Sweden. All rights reserved.
 * Copyright (C) 2010 Matthias Fuchs <[email protected]>, esd gmbh
 *
 * Known issues:
 *  - Transition from CAN_STATE_ERROR_WARNING to CAN_STATE_ERROR_ACTIVE is only
 *    reported after a call to do_get_berr_counter(), since firmware does not
 *    distinguish between ERROR_WARNING and ERROR_ACTIVE.
 *  - Hardware timestamps are not set for CAN Tx frames.
 */

#include <linux/completion.h>
#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/units.h>
#include <linux/usb.h>

#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/netlink.h>

#include "kvaser_usb.h"

/* Forward declarations */
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_kcan;
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc;
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt;

#define KVASER_USB_HYDRA_BULK_EP_IN_ADDR
#define KVASER_USB_HYDRA_BULK_EP_OUT_ADDR

#define KVASER_USB_HYDRA_MAX_TRANSID
#define KVASER_USB_HYDRA_MIN_TRANSID

/* Minihydra command IDs */
#define CMD_SET_BUSPARAMS_REQ
#define CMD_GET_BUSPARAMS_REQ
#define CMD_GET_BUSPARAMS_RESP
#define CMD_GET_CHIP_STATE_REQ
#define CMD_CHIP_STATE_EVENT
#define CMD_SET_DRIVERMODE_REQ
#define CMD_START_CHIP_REQ
#define CMD_START_CHIP_RESP
#define CMD_STOP_CHIP_REQ
#define CMD_STOP_CHIP_RESP
#define CMD_TX_CAN_MESSAGE
#define CMD_GET_CARD_INFO_REQ
#define CMD_GET_CARD_INFO_RESP
#define CMD_GET_SOFTWARE_INFO_REQ
#define CMD_GET_SOFTWARE_INFO_RESP
#define CMD_ERROR_EVENT
#define CMD_FLUSH_QUEUE
#define CMD_TX_ACKNOWLEDGE
#define CMD_FLUSH_QUEUE_RESP
#define CMD_SET_BUSPARAMS_FD_REQ
#define CMD_SET_BUSPARAMS_FD_RESP
#define CMD_SET_BUSPARAMS_RESP
#define CMD_GET_CAPABILITIES_REQ
#define CMD_GET_CAPABILITIES_RESP
#define CMD_RX_MESSAGE
#define CMD_MAP_CHANNEL_REQ
#define CMD_MAP_CHANNEL_RESP
#define CMD_GET_SOFTWARE_DETAILS_REQ
#define CMD_GET_SOFTWARE_DETAILS_RESP
#define CMD_EXTENDED

/* Minihydra extended command IDs */
#define CMD_TX_CAN_MESSAGE_FD
#define CMD_TX_ACKNOWLEDGE_FD
#define CMD_RX_MESSAGE_FD

/* Hydra commands are handled by different threads in firmware.
 * The threads are denoted hydra entity (HE). Each HE got a unique 6-bit
 * address. The address is used in hydra commands to get/set source and
 * destination HE. There are two predefined HE addresses, the remaining
 * addresses are different between devices and firmware versions. Hence, we need
 * to enumerate the addresses (see kvaser_usb_hydra_map_channel()).
 */

/* Well-known HE addresses */
#define KVASER_USB_HYDRA_HE_ADDRESS_ROUTER
#define KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL

#define KVASER_USB_HYDRA_TRANSID_CANHE
#define KVASER_USB_HYDRA_TRANSID_SYSDBG

struct kvaser_cmd_map_ch_req {} __packed;

struct kvaser_cmd_map_ch_res {} __packed;

struct kvaser_cmd_card_info {} __packed;

struct kvaser_cmd_sw_info {} __packed;

struct kvaser_cmd_sw_detail_req {} __packed;

/* Software detail flags */
#define KVASER_USB_HYDRA_SW_FLAG_FW_BETA
#define KVASER_USB_HYDRA_SW_FLAG_FW_BAD
#define KVASER_USB_HYDRA_SW_FLAG_FREQ_80M
#define KVASER_USB_HYDRA_SW_FLAG_EXT_CMD
#define KVASER_USB_HYDRA_SW_FLAG_CANFD
#define KVASER_USB_HYDRA_SW_FLAG_NONISO
#define KVASER_USB_HYDRA_SW_FLAG_EXT_CAP
#define KVASER_USB_HYDRA_SW_FLAG_CAN_FREQ_80M
struct kvaser_cmd_sw_detail_res {} __packed;

/* Sub commands for cap_req and cap_res */
#define KVASER_USB_HYDRA_CAP_CMD_LISTEN_MODE
#define KVASER_USB_HYDRA_CAP_CMD_ERR_REPORT
#define KVASER_USB_HYDRA_CAP_CMD_ONE_SHOT
struct kvaser_cmd_cap_req {} __packed;

/* Status codes for cap_res */
#define KVASER_USB_HYDRA_CAP_STAT_OK
#define KVASER_USB_HYDRA_CAP_STAT_NOT_IMPL
#define KVASER_USB_HYDRA_CAP_STAT_UNAVAIL
struct kvaser_cmd_cap_res {} __packed;

/* CMD_ERROR_EVENT error codes */
#define KVASER_USB_HYDRA_ERROR_EVENT_CAN
#define KVASER_USB_HYDRA_ERROR_EVENT_PARAM
struct kvaser_cmd_error_event {} __packed;

/* Chip state status flags. Used for chip_state_event and err_frame_data. */
#define KVASER_USB_HYDRA_BUS_ERR_ACT
#define KVASER_USB_HYDRA_BUS_ERR_PASS
#define KVASER_USB_HYDRA_BUS_BUS_OFF
struct kvaser_cmd_chip_state_event {} __packed;

/* Busparam modes */
#define KVASER_USB_HYDRA_BUS_MODE_CAN
#define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO
#define KVASER_USB_HYDRA_BUS_MODE_NONISO
struct kvaser_cmd_set_busparams {} __packed;

/* Busparam type */
#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN
#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD
struct kvaser_cmd_get_busparams_req {} __packed;

struct kvaser_cmd_get_busparams_res {} __packed;

/* Ctrl modes */
#define KVASER_USB_HYDRA_CTRLMODE_NORMAL
#define KVASER_USB_HYDRA_CTRLMODE_LISTEN
struct kvaser_cmd_set_ctrlmode {} __packed;

struct kvaser_err_frame_data {} __packed;

struct kvaser_cmd_rx_can {} __packed;

/* Extended CAN ID flag. Used in rx_can and tx_can */
#define KVASER_USB_HYDRA_EXTENDED_FRAME_ID
struct kvaser_cmd_tx_can {} __packed;

struct kvaser_cmd_header {} __packed;

struct kvaser_cmd {} __packed;

/* CAN frame flags. Used in rx_can, ext_rx_can, tx_can and ext_tx_can */
#define KVASER_USB_HYDRA_CF_FLAG_ERROR_FRAME
#define KVASER_USB_HYDRA_CF_FLAG_OVERRUN
#define KVASER_USB_HYDRA_CF_FLAG_REMOTE_FRAME
#define KVASER_USB_HYDRA_CF_FLAG_EXTENDED_ID
#define KVASER_USB_HYDRA_CF_FLAG_TX_ACK
/* CAN frame flags. Used in ext_rx_can and ext_tx_can */
#define KVASER_USB_HYDRA_CF_FLAG_OSM_NACK
#define KVASER_USB_HYDRA_CF_FLAG_ABL
#define KVASER_USB_HYDRA_CF_FLAG_FDF
#define KVASER_USB_HYDRA_CF_FLAG_BRS
#define KVASER_USB_HYDRA_CF_FLAG_ESI

/* KCAN packet header macros. Used in ext_rx_can and ext_tx_can */
#define KVASER_USB_KCAN_DATA_DLC_BITS
#define KVASER_USB_KCAN_DATA_DLC_SHIFT
#define KVASER_USB_KCAN_DATA_DLC_MASK

#define KVASER_USB_KCAN_DATA_BRS
#define KVASER_USB_KCAN_DATA_FDF
#define KVASER_USB_KCAN_DATA_OSM
#define KVASER_USB_KCAN_DATA_AREQ
#define KVASER_USB_KCAN_DATA_SRR
#define KVASER_USB_KCAN_DATA_RTR
#define KVASER_USB_KCAN_DATA_IDE
struct kvaser_cmd_ext_rx_can {} __packed;

struct kvaser_cmd_ext_tx_can {} __packed;

struct kvaser_cmd_ext_tx_ack {} __packed;

/* struct for extended commands (CMD_EXTENDED) */
struct kvaser_cmd_ext {} __packed;

struct kvaser_usb_net_hydra_priv {};

static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c =;

const struct can_bittiming_const kvaser_usb_flexc_bittiming_const =;

static const struct can_bittiming_const kvaser_usb_hydra_rt_bittiming_c =;

static const struct can_bittiming_const kvaser_usb_hydra_rtd_bittiming_c =;

#define KVASER_USB_HYDRA_TRANSID_BITS
#define KVASER_USB_HYDRA_TRANSID_MASK
#define KVASER_USB_HYDRA_HE_ADDR_SRC_MASK
#define KVASER_USB_HYDRA_HE_ADDR_DEST_MASK
#define KVASER_USB_HYDRA_HE_ADDR_SRC_BITS
static inline u16 kvaser_usb_hydra_get_cmd_transid(const struct kvaser_cmd *cmd)
{}

static inline void kvaser_usb_hydra_set_cmd_transid(struct kvaser_cmd *cmd,
						    u16 transid)
{}

static inline u8 kvaser_usb_hydra_get_cmd_src_he(const struct kvaser_cmd *cmd)
{}

static inline void kvaser_usb_hydra_set_cmd_dest_he(struct kvaser_cmd *cmd,
						    u8 dest_he)
{}

static u8 kvaser_usb_hydra_channel_from_cmd(const struct kvaser_usb *dev,
					    const struct kvaser_cmd *cmd)
{}

static u16 kvaser_usb_hydra_get_next_transid(struct kvaser_usb *dev)
{}

static size_t kvaser_usb_hydra_cmd_size(struct kvaser_cmd *cmd)
{}

static struct kvaser_usb_net_priv *
kvaser_usb_hydra_net_priv_from_cmd(const struct kvaser_usb *dev,
				   const struct kvaser_cmd *cmd)
{}

static ktime_t
kvaser_usb_hydra_ktime_from_rx_cmd(const struct kvaser_usb_dev_cfg *cfg,
				   const struct kvaser_cmd *cmd)
{}

static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev,
					    u8 cmd_no, int channel)
{}

static int
kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv,
				       u8 cmd_no)
{}

/* This function is used for synchronously waiting on hydra control commands.
 * Note: Compared to kvaser_usb_hydra_read_bulk_callback(), we never need to
 *       handle partial hydra commands. Since hydra control commands are always
 *       non-extended commands.
 */
static int kvaser_usb_hydra_wait_cmd(const struct kvaser_usb *dev, u8 cmd_no,
				     struct kvaser_cmd *cmd)
{}

static int kvaser_usb_hydra_map_channel_resp(struct kvaser_usb *dev,
					     const struct kvaser_cmd *cmd)
{}

static int kvaser_usb_hydra_map_channel(struct kvaser_usb *dev, u16 transid,
					u8 channel, const char *name)
{}

static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev,
						  u16 cap_cmd_req, u16 *status)
{}

static void kvaser_usb_hydra_start_chip_reply(const struct kvaser_usb *dev,
					      const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_stop_chip_reply(const struct kvaser_usb *dev,
					     const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev,
					       const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev,
						 const struct kvaser_cmd *cmd)
{}

static void
kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
					 u8 bus_status,
					 const struct can_berr_counter *bec,
					 enum can_state *new_state)
{}

static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
					  u8 bus_status,
					  const struct can_berr_counter *bec)
{}

static void kvaser_usb_hydra_state_event(const struct kvaser_usb *dev,
					 const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_error_event_parameter(const struct kvaser_usb *dev,
						   const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_error_event(const struct kvaser_usb *dev,
					 const struct kvaser_cmd *cmd)
{}

static void
kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
			     const struct kvaser_err_frame_data *err_frame_data,
			     ktime_t hwtstamp)
{}

static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv,
					   const struct kvaser_cmd_ext *cmd)
{}

static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev,
					    const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_rx_msg_std(const struct kvaser_usb *dev,
					const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_rx_msg_ext(const struct kvaser_usb *dev,
					const struct kvaser_cmd_ext *cmd)
{}

static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev,
					    const struct kvaser_cmd *cmd)
{}

static void kvaser_usb_hydra_handle_cmd_ext(const struct kvaser_usb *dev,
					    const struct kvaser_cmd_ext *cmd)
{}

static void kvaser_usb_hydra_handle_cmd(const struct kvaser_usb *dev,
					const struct kvaser_cmd *cmd)
{}

static void *
kvaser_usb_hydra_frame_to_cmd_ext(const struct kvaser_usb_net_priv *priv,
				  const struct sk_buff *skb, int *cmd_len,
				  u16 transid)
{}

static void *
kvaser_usb_hydra_frame_to_cmd_std(const struct kvaser_usb_net_priv *priv,
				  const struct sk_buff *skb, int *cmd_len,
				  u16 transid)
{}

static int kvaser_usb_hydra_set_mode(struct net_device *netdev,
				     enum can_mode mode)
{}

static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
					  int busparams_type)
{}

static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
					  const struct kvaser_usb_busparams *busparams)
{}

static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
					       const struct kvaser_usb_busparams *busparams)
{}

static int kvaser_usb_hydra_get_berr_counter(const struct net_device *netdev,
					     struct can_berr_counter *bec)
{}

static int kvaser_usb_hydra_setup_endpoints(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_get_card_info(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_get_capabilities(struct kvaser_usb *dev)
{}

static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
{}

static int kvaser_usb_hydra_flush_queue(struct kvaser_usb_net_priv *priv)
{}

/* A single extended hydra command can be transmitted in multiple transfers
 * We have to buffer partial hydra commands, and handle them on next callback.
 */
static void kvaser_usb_hydra_read_bulk_callback(struct kvaser_usb *dev,
						void *buf, int len)
{}

static void *
kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
			      const struct sk_buff *skb, int *cmd_len,
			      u16 transid)
{}

const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops =;

static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_kcan =;

static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc =;

static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt =;