Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /* Driver for ETAS GmbH ES58X USB CAN(-FD) Bus Interfaces.
0004  *
0005  * File es58x_fd.c: Adds support to ETAS ES582.1 and ES584.1 (naming
0006  * convention: we use the term "ES58X FD" when referring to those two
0007  * variants together).
0008  *
0009  * Copyright (c) 2019 Robert Bosch Engineering and Business Solutions. All rights reserved.
0010  * Copyright (c) 2020 ETAS K.K.. All rights reserved.
0011  * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/units.h>
0016 #include <asm/unaligned.h>
0017 
0018 #include "es58x_core.h"
0019 #include "es58x_fd.h"
0020 
0021 /**
0022  * es58x_fd_sizeof_rx_tx_msg() - Calculate the actual length of the
0023  *  structure of a rx or tx message.
0024  * @msg: message of variable length, must have a dlc and a len fields.
0025  *
0026  * Even if RTR frames have actually no payload, the ES58X devices
0027  * still expect it. Must be a macro in order to accept several types
0028  * (struct es58x_fd_tx_can_msg and struct es58x_fd_rx_can_msg) as an
0029  * input.
0030  *
0031  * Return: length of the message.
0032  */
0033 #define es58x_fd_sizeof_rx_tx_msg(msg)                  \
0034 ({                                  \
0035     typeof(msg) __msg = (msg);                  \
0036     size_t __msg_len;                       \
0037                                     \
0038     if (__msg.flags & ES58X_FLAG_FD_DATA)               \
0039         __msg_len = canfd_sanitize_len(__msg.len);      \
0040     else                                \
0041         __msg_len = can_cc_dlc2len(__msg.dlc);          \
0042                                     \
0043     offsetof(typeof(__msg), data[__msg_len]);           \
0044 })
0045 
0046 static enum es58x_fd_cmd_type es58x_fd_cmd_type(struct net_device *netdev)
0047 {
0048     u32 ctrlmode = es58x_priv(netdev)->can.ctrlmode;
0049 
0050     if (ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO))
0051         return ES58X_FD_CMD_TYPE_CANFD;
0052     else
0053         return ES58X_FD_CMD_TYPE_CAN;
0054 }
0055 
0056 static u16 es58x_fd_get_msg_len(const union es58x_urb_cmd *urb_cmd)
0057 {
0058     return get_unaligned_le16(&urb_cmd->es58x_fd_urb_cmd.msg_len);
0059 }
0060 
0061 static int es58x_fd_echo_msg(struct net_device *netdev,
0062                  const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0063 {
0064     struct es58x_priv *priv = es58x_priv(netdev);
0065     const struct es58x_fd_echo_msg *echo_msg;
0066     struct es58x_device *es58x_dev = priv->es58x_dev;
0067     u64 *tstamps = es58x_dev->timestamps;
0068     u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0069     int i, num_element;
0070     u32 rcv_packet_idx;
0071 
0072     const u32 mask = GENMASK(BITS_PER_TYPE(mask) - 1,
0073                  BITS_PER_TYPE(echo_msg->packet_idx));
0074 
0075     num_element = es58x_msg_num_element(es58x_dev->dev,
0076                         es58x_fd_urb_cmd->echo_msg,
0077                         msg_len);
0078     if (num_element < 0)
0079         return num_element;
0080     echo_msg = es58x_fd_urb_cmd->echo_msg;
0081 
0082     rcv_packet_idx = (priv->tx_tail & mask) | echo_msg[0].packet_idx;
0083     for (i = 0; i < num_element; i++) {
0084         if ((u8)rcv_packet_idx != echo_msg[i].packet_idx) {
0085             netdev_err(netdev, "Packet idx jumped from %u to %u\n",
0086                    (u8)rcv_packet_idx - 1,
0087                    echo_msg[i].packet_idx);
0088             return -EBADMSG;
0089         }
0090 
0091         tstamps[i] = get_unaligned_le64(&echo_msg[i].timestamp);
0092         rcv_packet_idx++;
0093     }
0094 
0095     return es58x_can_get_echo_skb(netdev, priv->tx_tail, tstamps, num_element);
0096 }
0097 
0098 static int es58x_fd_rx_can_msg(struct net_device *netdev,
0099                    const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0100 {
0101     struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
0102     const u8 *rx_can_msg_buf = es58x_fd_urb_cmd->rx_can_msg_buf;
0103     u16 rx_can_msg_buf_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0104     int pkts, ret;
0105 
0106     ret = es58x_check_msg_max_len(es58x_dev->dev,
0107                       es58x_fd_urb_cmd->rx_can_msg_buf,
0108                       rx_can_msg_buf_len);
0109     if (ret)
0110         return ret;
0111 
0112     for (pkts = 0; rx_can_msg_buf_len > 0; pkts++) {
0113         const struct es58x_fd_rx_can_msg *rx_can_msg =
0114             (const struct es58x_fd_rx_can_msg *)rx_can_msg_buf;
0115         bool is_can_fd = !!(rx_can_msg->flags & ES58X_FLAG_FD_DATA);
0116         /* rx_can_msg_len is the length of the rx_can_msg
0117          * buffer. Not to be confused with rx_can_msg->len
0118          * which is the length of the CAN payload
0119          * rx_can_msg->data.
0120          */
0121         u16 rx_can_msg_len = es58x_fd_sizeof_rx_tx_msg(*rx_can_msg);
0122 
0123         if (rx_can_msg_len > rx_can_msg_buf_len) {
0124             netdev_err(netdev,
0125                    "%s: Expected a rx_can_msg of size %d but only %d bytes are left in rx_can_msg_buf\n",
0126                    __func__,
0127                    rx_can_msg_len, rx_can_msg_buf_len);
0128             return -EMSGSIZE;
0129         }
0130         if (rx_can_msg->len > CANFD_MAX_DLEN) {
0131             netdev_err(netdev,
0132                    "%s: Data length is %d but maximum should be %d\n",
0133                    __func__, rx_can_msg->len, CANFD_MAX_DLEN);
0134             return -EMSGSIZE;
0135         }
0136 
0137         if (netif_running(netdev)) {
0138             u64 tstamp = get_unaligned_le64(&rx_can_msg->timestamp);
0139             canid_t can_id = get_unaligned_le32(&rx_can_msg->can_id);
0140             u8 dlc;
0141 
0142             if (is_can_fd)
0143                 dlc = can_fd_len2dlc(rx_can_msg->len);
0144             else
0145                 dlc = rx_can_msg->dlc;
0146 
0147             ret = es58x_rx_can_msg(netdev, tstamp, rx_can_msg->data,
0148                            can_id, rx_can_msg->flags, dlc);
0149             if (ret)
0150                 break;
0151         }
0152 
0153         rx_can_msg_buf_len -= rx_can_msg_len;
0154         rx_can_msg_buf += rx_can_msg_len;
0155     }
0156 
0157     if (!netif_running(netdev)) {
0158         if (net_ratelimit())
0159             netdev_info(netdev,
0160                     "%s: %s is down, dropping %d rx packets\n",
0161                     __func__, netdev->name, pkts);
0162         netdev->stats.rx_dropped += pkts;
0163     }
0164 
0165     return ret;
0166 }
0167 
0168 static int es58x_fd_rx_event_msg(struct net_device *netdev,
0169                  const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0170 {
0171     struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
0172     u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0173     const struct es58x_fd_rx_event_msg *rx_event_msg;
0174     int ret;
0175 
0176     rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg;
0177     ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len);
0178     if (ret)
0179         return ret;
0180 
0181     return es58x_rx_err_msg(netdev, rx_event_msg->error_code,
0182                 rx_event_msg->event_code,
0183                 get_unaligned_le64(&rx_event_msg->timestamp));
0184 }
0185 
0186 static int es58x_fd_rx_cmd_ret_u32(struct net_device *netdev,
0187                    const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd,
0188                    enum es58x_ret_type cmd_ret_type)
0189 {
0190     struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
0191     u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0192     int ret;
0193 
0194     ret = es58x_check_msg_len(es58x_dev->dev,
0195                   es58x_fd_urb_cmd->rx_cmd_ret_le32, msg_len);
0196     if (ret)
0197         return ret;
0198 
0199     return es58x_rx_cmd_ret_u32(netdev, cmd_ret_type,
0200                     get_unaligned_le32(&es58x_fd_urb_cmd->rx_cmd_ret_le32));
0201 }
0202 
0203 static int es58x_fd_tx_ack_msg(struct net_device *netdev,
0204                    const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0205 {
0206     struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
0207     const struct es58x_fd_tx_ack_msg *tx_ack_msg;
0208     u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0209     int ret;
0210 
0211     tx_ack_msg = &es58x_fd_urb_cmd->tx_ack_msg;
0212     ret = es58x_check_msg_len(es58x_dev->dev, *tx_ack_msg, msg_len);
0213     if (ret)
0214         return ret;
0215 
0216     return es58x_tx_ack_msg(netdev,
0217                 get_unaligned_le16(&tx_ack_msg->tx_free_entries),
0218                 get_unaligned_le32(&tx_ack_msg->rx_cmd_ret_le32));
0219 }
0220 
0221 static int es58x_fd_can_cmd_id(struct es58x_device *es58x_dev,
0222                    const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0223 {
0224     struct net_device *netdev;
0225     int ret;
0226 
0227     ret = es58x_get_netdev(es58x_dev, es58x_fd_urb_cmd->channel_idx,
0228                    ES58X_FD_CHANNEL_IDX_OFFSET, &netdev);
0229     if (ret)
0230         return ret;
0231 
0232     switch ((enum es58x_fd_can_cmd_id)es58x_fd_urb_cmd->cmd_id) {
0233     case ES58X_FD_CAN_CMD_ID_ENABLE_CHANNEL:
0234         return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd,
0235                            ES58X_RET_TYPE_ENABLE_CHANNEL);
0236 
0237     case ES58X_FD_CAN_CMD_ID_DISABLE_CHANNEL:
0238         return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd,
0239                            ES58X_RET_TYPE_DISABLE_CHANNEL);
0240 
0241     case ES58X_FD_CAN_CMD_ID_TX_MSG:
0242         return es58x_fd_tx_ack_msg(netdev, es58x_fd_urb_cmd);
0243 
0244     case ES58X_FD_CAN_CMD_ID_ECHO_MSG:
0245         return es58x_fd_echo_msg(netdev, es58x_fd_urb_cmd);
0246 
0247     case ES58X_FD_CAN_CMD_ID_RX_MSG:
0248         return es58x_fd_rx_can_msg(netdev, es58x_fd_urb_cmd);
0249 
0250     case ES58X_FD_CAN_CMD_ID_RESET_RX:
0251         return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd,
0252                            ES58X_RET_TYPE_RESET_RX);
0253 
0254     case ES58X_FD_CAN_CMD_ID_RESET_TX:
0255         return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd,
0256                            ES58X_RET_TYPE_RESET_TX);
0257 
0258     case ES58X_FD_CAN_CMD_ID_ERROR_OR_EVENT_MSG:
0259         return es58x_fd_rx_event_msg(netdev, es58x_fd_urb_cmd);
0260 
0261     default:
0262         return -EBADRQC;
0263     }
0264 }
0265 
0266 static int es58x_fd_device_cmd_id(struct es58x_device *es58x_dev,
0267                   const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd)
0268 {
0269     u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len);
0270     int ret;
0271 
0272     switch ((enum es58x_fd_dev_cmd_id)es58x_fd_urb_cmd->cmd_id) {
0273     case ES58X_FD_DEV_CMD_ID_TIMESTAMP:
0274         ret = es58x_check_msg_len(es58x_dev->dev,
0275                       es58x_fd_urb_cmd->timestamp, msg_len);
0276         if (ret)
0277             return ret;
0278         es58x_rx_timestamp(es58x_dev,
0279                    get_unaligned_le64(&es58x_fd_urb_cmd->timestamp));
0280         return 0;
0281 
0282     default:
0283         return -EBADRQC;
0284     }
0285 }
0286 
0287 static int es58x_fd_handle_urb_cmd(struct es58x_device *es58x_dev,
0288                    const union es58x_urb_cmd *urb_cmd)
0289 {
0290     const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd;
0291     int ret;
0292 
0293     es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd;
0294 
0295     switch ((enum es58x_fd_cmd_type)es58x_fd_urb_cmd->cmd_type) {
0296     case ES58X_FD_CMD_TYPE_CAN:
0297     case ES58X_FD_CMD_TYPE_CANFD:
0298         ret = es58x_fd_can_cmd_id(es58x_dev, es58x_fd_urb_cmd);
0299         break;
0300 
0301     case ES58X_FD_CMD_TYPE_DEVICE:
0302         ret = es58x_fd_device_cmd_id(es58x_dev, es58x_fd_urb_cmd);
0303         break;
0304 
0305     default:
0306         ret = -EBADRQC;
0307         break;
0308     }
0309 
0310     if (ret == -EBADRQC)
0311         dev_err(es58x_dev->dev,
0312             "%s: Unknown command type (0x%02X) and command ID (0x%02X) combination\n",
0313             __func__, es58x_fd_urb_cmd->cmd_type,
0314             es58x_fd_urb_cmd->cmd_id);
0315 
0316     return ret;
0317 }
0318 
0319 static void es58x_fd_fill_urb_header(union es58x_urb_cmd *urb_cmd, u8 cmd_type,
0320                      u8 cmd_id, u8 channel_idx, u16 msg_len)
0321 {
0322     struct es58x_fd_urb_cmd *es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd;
0323 
0324     es58x_fd_urb_cmd->SOF = cpu_to_le16(es58x_fd_param.tx_start_of_frame);
0325     es58x_fd_urb_cmd->cmd_type = cmd_type;
0326     es58x_fd_urb_cmd->cmd_id = cmd_id;
0327     es58x_fd_urb_cmd->channel_idx = channel_idx;
0328     es58x_fd_urb_cmd->msg_len = cpu_to_le16(msg_len);
0329 }
0330 
0331 static int es58x_fd_tx_can_msg(struct es58x_priv *priv,
0332                    const struct sk_buff *skb)
0333 {
0334     struct es58x_device *es58x_dev = priv->es58x_dev;
0335     union es58x_urb_cmd *urb_cmd = priv->tx_urb->transfer_buffer;
0336     struct es58x_fd_urb_cmd *es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd;
0337     struct can_frame *cf = (struct can_frame *)skb->data;
0338     struct es58x_fd_tx_can_msg *tx_can_msg;
0339     bool is_fd = can_is_canfd_skb(skb);
0340     u16 msg_len;
0341     int ret;
0342 
0343     if (priv->tx_can_msg_cnt == 0) {
0344         msg_len = 0;
0345         es58x_fd_fill_urb_header(urb_cmd,
0346                      is_fd ? ES58X_FD_CMD_TYPE_CANFD
0347                            : ES58X_FD_CMD_TYPE_CAN,
0348                      ES58X_FD_CAN_CMD_ID_TX_MSG_NO_ACK,
0349                      priv->channel_idx, msg_len);
0350     } else {
0351         msg_len = es58x_fd_get_msg_len(urb_cmd);
0352     }
0353 
0354     ret = es58x_check_msg_max_len(es58x_dev->dev,
0355                       es58x_fd_urb_cmd->tx_can_msg_buf,
0356                       msg_len + sizeof(*tx_can_msg));
0357     if (ret)
0358         return ret;
0359 
0360     /* Fill message contents. */
0361     tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len];
0362     tx_can_msg->packet_idx = (u8)priv->tx_head;
0363     put_unaligned_le32(es58x_get_raw_can_id(cf), &tx_can_msg->can_id);
0364     tx_can_msg->flags = (u8)es58x_get_flags(skb);
0365     if (is_fd)
0366         tx_can_msg->len = cf->len;
0367     else
0368         tx_can_msg->dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
0369     memcpy(tx_can_msg->data, cf->data, cf->len);
0370 
0371     /* Calculate new sizes */
0372     msg_len += es58x_fd_sizeof_rx_tx_msg(*tx_can_msg);
0373     priv->tx_urb->transfer_buffer_length = es58x_get_urb_cmd_len(es58x_dev,
0374                                      msg_len);
0375     put_unaligned_le16(msg_len, &es58x_fd_urb_cmd->msg_len);
0376 
0377     return 0;
0378 }
0379 
0380 static void es58x_fd_convert_bittiming(struct es58x_fd_bittiming *es58x_fd_bt,
0381                        struct can_bittiming *bt)
0382 {
0383     /* The actual value set in the hardware registers is one less
0384      * than the functional value.
0385      */
0386     const int offset = 1;
0387 
0388     es58x_fd_bt->bitrate = cpu_to_le32(bt->bitrate);
0389     es58x_fd_bt->tseg1 =
0390         cpu_to_le16(bt->prop_seg + bt->phase_seg1 - offset);
0391     es58x_fd_bt->tseg2 = cpu_to_le16(bt->phase_seg2 - offset);
0392     es58x_fd_bt->brp = cpu_to_le16(bt->brp - offset);
0393     es58x_fd_bt->sjw = cpu_to_le16(bt->sjw - offset);
0394 }
0395 
0396 static int es58x_fd_enable_channel(struct es58x_priv *priv)
0397 {
0398     struct es58x_device *es58x_dev = priv->es58x_dev;
0399     struct net_device *netdev = es58x_dev->netdev[priv->channel_idx];
0400     struct es58x_fd_tx_conf_msg tx_conf_msg = { 0 };
0401     u32 ctrlmode;
0402     size_t conf_len = 0;
0403 
0404     es58x_fd_convert_bittiming(&tx_conf_msg.nominal_bittiming,
0405                    &priv->can.bittiming);
0406     ctrlmode = priv->can.ctrlmode;
0407 
0408     if (ctrlmode & CAN_CTRLMODE_3_SAMPLES)
0409         tx_conf_msg.samples_per_bit = ES58X_SAMPLES_PER_BIT_THREE;
0410     else
0411         tx_conf_msg.samples_per_bit = ES58X_SAMPLES_PER_BIT_ONE;
0412     tx_conf_msg.sync_edge = ES58X_SYNC_EDGE_SINGLE;
0413     tx_conf_msg.physical_layer = ES58X_PHYSICAL_LAYER_HIGH_SPEED;
0414     tx_conf_msg.echo_mode = ES58X_ECHO_ON;
0415     if (ctrlmode & CAN_CTRLMODE_LISTENONLY)
0416         tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_PASSIVE;
0417     else
0418         tx_conf_msg.ctrlmode |=  ES58X_FD_CTRLMODE_ACTIVE;
0419 
0420     if (ctrlmode & CAN_CTRLMODE_FD_NON_ISO) {
0421         tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_FD_NON_ISO;
0422         tx_conf_msg.canfd_enabled = 1;
0423     } else if (ctrlmode & CAN_CTRLMODE_FD) {
0424         tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_FD;
0425         tx_conf_msg.canfd_enabled = 1;
0426     }
0427 
0428     if (tx_conf_msg.canfd_enabled) {
0429         es58x_fd_convert_bittiming(&tx_conf_msg.data_bittiming,
0430                        &priv->can.data_bittiming);
0431 
0432         if (can_tdc_is_enabled(&priv->can)) {
0433             tx_conf_msg.tdc_enabled = 1;
0434             tx_conf_msg.tdco = cpu_to_le16(priv->can.tdc.tdco);
0435             tx_conf_msg.tdcf = cpu_to_le16(priv->can.tdc.tdcf);
0436         }
0437 
0438         conf_len = ES58X_FD_CANFD_CONF_LEN;
0439     } else {
0440         conf_len = ES58X_FD_CAN_CONF_LEN;
0441     }
0442 
0443     return es58x_send_msg(es58x_dev, es58x_fd_cmd_type(netdev),
0444                   ES58X_FD_CAN_CMD_ID_ENABLE_CHANNEL,
0445                   &tx_conf_msg, conf_len, priv->channel_idx);
0446 }
0447 
0448 static int es58x_fd_disable_channel(struct es58x_priv *priv)
0449 {
0450     /* The type (ES58X_FD_CMD_TYPE_CAN or ES58X_FD_CMD_TYPE_CANFD) does
0451      * not matter here.
0452      */
0453     return es58x_send_msg(priv->es58x_dev, ES58X_FD_CMD_TYPE_CAN,
0454                   ES58X_FD_CAN_CMD_ID_DISABLE_CHANNEL,
0455                   ES58X_EMPTY_MSG, 0, priv->channel_idx);
0456 }
0457 
0458 static int es58x_fd_get_timestamp(struct es58x_device *es58x_dev)
0459 {
0460     return es58x_send_msg(es58x_dev, ES58X_FD_CMD_TYPE_DEVICE,
0461                   ES58X_FD_DEV_CMD_ID_TIMESTAMP, ES58X_EMPTY_MSG,
0462                   0, ES58X_CHANNEL_IDX_NA);
0463 }
0464 
0465 /* Nominal bittiming constants for ES582.1 and ES584.1 as specified in
0466  * the microcontroller datasheet: "SAM E70/S70/V70/V71 Family" section
0467  * 49.6.8 "MCAN Nominal Bit Timing and Prescaler Register" from
0468  * Microchip.
0469  *
0470  * The values from the specification are the hardware register
0471  * values. To convert them to the functional values, all ranges were
0472  * incremented by 1 (e.g. range [0..n-1] changed to [1..n]).
0473  */
0474 static const struct can_bittiming_const es58x_fd_nom_bittiming_const = {
0475     .name = "ES582.1/ES584.1",
0476     .tseg1_min = 2,
0477     .tseg1_max = 256,
0478     .tseg2_min = 2,
0479     .tseg2_max = 128,
0480     .sjw_max = 128,
0481     .brp_min = 1,
0482     .brp_max = 512,
0483     .brp_inc = 1
0484 };
0485 
0486 /* Data bittiming constants for ES582.1 and ES584.1 as specified in
0487  * the microcontroller datasheet: "SAM E70/S70/V70/V71 Family" section
0488  * 49.6.4 "MCAN Data Bit Timing and Prescaler Register" from
0489  * Microchip.
0490  */
0491 static const struct can_bittiming_const es58x_fd_data_bittiming_const = {
0492     .name = "ES582.1/ES584.1",
0493     .tseg1_min = 2,
0494     .tseg1_max = 32,
0495     .tseg2_min = 1,
0496     .tseg2_max = 16,
0497     .sjw_max = 8,
0498     .brp_min = 1,
0499     .brp_max = 32,
0500     .brp_inc = 1
0501 };
0502 
0503 /* Transmission Delay Compensation constants for ES582.1 and ES584.1
0504  * as specified in the microcontroller datasheet: "SAM E70/S70/V70/V71
0505  * Family" section 49.6.15 "MCAN Transmitter Delay Compensation
0506  * Register" from Microchip.
0507  */
0508 static const struct can_tdc_const es58x_tdc_const = {
0509     .tdcv_min = 0,
0510     .tdcv_max = 0, /* Manual mode not supported. */
0511     .tdco_min = 0,
0512     .tdco_max = 127,
0513     .tdcf_min = 0,
0514     .tdcf_max = 127
0515 };
0516 
0517 const struct es58x_parameters es58x_fd_param = {
0518     .bittiming_const = &es58x_fd_nom_bittiming_const,
0519     .data_bittiming_const = &es58x_fd_data_bittiming_const,
0520     .tdc_const = &es58x_tdc_const,
0521     /* The devices use NXP TJA1044G transievers which guarantee
0522      * the timing for data rates up to 5 Mbps. Bitrates up to 8
0523      * Mbps work in an optimal environment but are not recommended
0524      * for production environment.
0525      */
0526     .bitrate_max = 8 * MEGA /* BPS */,
0527     .clock = {.freq = 80 * MEGA /* Hz */},
0528     .ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY |
0529         CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO |
0530         CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_TDC_AUTO,
0531     .tx_start_of_frame = 0xCEFA,    /* FACE in little endian */
0532     .rx_start_of_frame = 0xFECA,    /* CAFE in little endian */
0533     .tx_urb_cmd_max_len = ES58X_FD_TX_URB_CMD_MAX_LEN,
0534     .rx_urb_cmd_max_len = ES58X_FD_RX_URB_CMD_MAX_LEN,
0535     /* Size of internal device TX queue is 500.
0536      *
0537      * However, when reaching value around 278, the device's busy
0538      * LED turns on and thus maximum value of 500 is never reached
0539      * in practice. Also, when this value is too high, some error
0540      * on the echo_msg were witnessed when the device is
0541      * recovering from bus off.
0542      *
0543      * For above reasons, a value that would prevent the device
0544      * from becoming busy was chosen. In practice, BQL would
0545      * prevent the value from even getting closer to below
0546      * maximum, so no impact on performance was measured.
0547      */
0548     .fifo_mask = 255, /* echo_skb_max = 256 */
0549     .dql_min_limit = CAN_FRAME_LEN_MAX * 15, /* Empirical value. */
0550     .tx_bulk_max = ES58X_FD_TX_BULK_MAX,
0551     .urb_cmd_header_len = ES58X_FD_URB_CMD_HEADER_LEN,
0552     .rx_urb_max = ES58X_RX_URBS_MAX,
0553     .tx_urb_max = ES58X_TX_URBS_MAX
0554 };
0555 
0556 const struct es58x_operators es58x_fd_ops = {
0557     .get_msg_len = es58x_fd_get_msg_len,
0558     .handle_urb_cmd = es58x_fd_handle_urb_cmd,
0559     .fill_urb_header = es58x_fd_fill_urb_header,
0560     .tx_can_msg = es58x_fd_tx_can_msg,
0561     .enable_channel = es58x_fd_enable_channel,
0562     .disable_channel = es58x_fd_disable_channel,
0563     .reset_device = NULL, /* Not implemented in the device firmware. */
0564     .get_timestamp = es58x_fd_get_timestamp
0565 };