es58x_fd.c (17890B)
1// SPDX-License-Identifier: GPL-2.0 2 3/* Driver for ETAS GmbH ES58X USB CAN(-FD) Bus Interfaces. 4 * 5 * File es58x_fd.c: Adds support to ETAS ES582.1 and ES584.1 (naming 6 * convention: we use the term "ES58X FD" when referring to those two 7 * variants together). 8 * 9 * Copyright (c) 2019 Robert Bosch Engineering and Business Solutions. All rights reserved. 10 * Copyright (c) 2020 ETAS K.K.. All rights reserved. 11 * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr> 12 */ 13 14#include <linux/kernel.h> 15#include <linux/units.h> 16#include <asm/unaligned.h> 17 18#include "es58x_core.h" 19#include "es58x_fd.h" 20 21/** 22 * es58x_fd_sizeof_rx_tx_msg() - Calculate the actual length of the 23 * structure of a rx or tx message. 24 * @msg: message of variable length, must have a dlc and a len fields. 25 * 26 * Even if RTR frames have actually no payload, the ES58X devices 27 * still expect it. Must be a macro in order to accept several types 28 * (struct es58x_fd_tx_can_msg and struct es58x_fd_rx_can_msg) as an 29 * input. 30 * 31 * Return: length of the message. 32 */ 33#define es58x_fd_sizeof_rx_tx_msg(msg) \ 34({ \ 35 typeof(msg) __msg = (msg); \ 36 size_t __msg_len; \ 37 \ 38 if (__msg.flags & ES58X_FLAG_FD_DATA) \ 39 __msg_len = canfd_sanitize_len(__msg.len); \ 40 else \ 41 __msg_len = can_cc_dlc2len(__msg.dlc); \ 42 \ 43 offsetof(typeof(__msg), data[__msg_len]); \ 44}) 45 46static enum es58x_fd_cmd_type es58x_fd_cmd_type(struct net_device *netdev) 47{ 48 u32 ctrlmode = es58x_priv(netdev)->can.ctrlmode; 49 50 if (ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO)) 51 return ES58X_FD_CMD_TYPE_CANFD; 52 else 53 return ES58X_FD_CMD_TYPE_CAN; 54} 55 56static u16 es58x_fd_get_msg_len(const union es58x_urb_cmd *urb_cmd) 57{ 58 return get_unaligned_le16(&urb_cmd->es58x_fd_urb_cmd.msg_len); 59} 60 61static int es58x_fd_echo_msg(struct net_device *netdev, 62 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 63{ 64 struct es58x_priv *priv = es58x_priv(netdev); 65 const struct es58x_fd_echo_msg *echo_msg; 66 struct es58x_device *es58x_dev = priv->es58x_dev; 67 u64 *tstamps = es58x_dev->timestamps; 68 u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 69 int i, num_element; 70 u32 rcv_packet_idx; 71 72 const u32 mask = GENMASK(BITS_PER_TYPE(mask) - 1, 73 BITS_PER_TYPE(echo_msg->packet_idx)); 74 75 num_element = es58x_msg_num_element(es58x_dev->dev, 76 es58x_fd_urb_cmd->echo_msg, 77 msg_len); 78 if (num_element < 0) 79 return num_element; 80 echo_msg = es58x_fd_urb_cmd->echo_msg; 81 82 rcv_packet_idx = (priv->tx_tail & mask) | echo_msg[0].packet_idx; 83 for (i = 0; i < num_element; i++) { 84 if ((u8)rcv_packet_idx != echo_msg[i].packet_idx) { 85 netdev_err(netdev, "Packet idx jumped from %u to %u\n", 86 (u8)rcv_packet_idx - 1, 87 echo_msg[i].packet_idx); 88 return -EBADMSG; 89 } 90 91 tstamps[i] = get_unaligned_le64(&echo_msg[i].timestamp); 92 rcv_packet_idx++; 93 } 94 95 return es58x_can_get_echo_skb(netdev, priv->tx_tail, tstamps, num_element); 96} 97 98static int es58x_fd_rx_can_msg(struct net_device *netdev, 99 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 100{ 101 struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev; 102 const u8 *rx_can_msg_buf = es58x_fd_urb_cmd->rx_can_msg_buf; 103 u16 rx_can_msg_buf_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 104 int pkts, ret; 105 106 ret = es58x_check_msg_max_len(es58x_dev->dev, 107 es58x_fd_urb_cmd->rx_can_msg_buf, 108 rx_can_msg_buf_len); 109 if (ret) 110 return ret; 111 112 for (pkts = 0; rx_can_msg_buf_len > 0; pkts++) { 113 const struct es58x_fd_rx_can_msg *rx_can_msg = 114 (const struct es58x_fd_rx_can_msg *)rx_can_msg_buf; 115 bool is_can_fd = !!(rx_can_msg->flags & ES58X_FLAG_FD_DATA); 116 /* rx_can_msg_len is the length of the rx_can_msg 117 * buffer. Not to be confused with rx_can_msg->len 118 * which is the length of the CAN payload 119 * rx_can_msg->data. 120 */ 121 u16 rx_can_msg_len = es58x_fd_sizeof_rx_tx_msg(*rx_can_msg); 122 123 if (rx_can_msg_len > rx_can_msg_buf_len) { 124 netdev_err(netdev, 125 "%s: Expected a rx_can_msg of size %d but only %d bytes are left in rx_can_msg_buf\n", 126 __func__, 127 rx_can_msg_len, rx_can_msg_buf_len); 128 return -EMSGSIZE; 129 } 130 if (rx_can_msg->len > CANFD_MAX_DLEN) { 131 netdev_err(netdev, 132 "%s: Data length is %d but maximum should be %d\n", 133 __func__, rx_can_msg->len, CANFD_MAX_DLEN); 134 return -EMSGSIZE; 135 } 136 137 if (netif_running(netdev)) { 138 u64 tstamp = get_unaligned_le64(&rx_can_msg->timestamp); 139 canid_t can_id = get_unaligned_le32(&rx_can_msg->can_id); 140 u8 dlc; 141 142 if (is_can_fd) 143 dlc = can_fd_len2dlc(rx_can_msg->len); 144 else 145 dlc = rx_can_msg->dlc; 146 147 ret = es58x_rx_can_msg(netdev, tstamp, rx_can_msg->data, 148 can_id, rx_can_msg->flags, dlc); 149 if (ret) 150 break; 151 } 152 153 rx_can_msg_buf_len -= rx_can_msg_len; 154 rx_can_msg_buf += rx_can_msg_len; 155 } 156 157 if (!netif_running(netdev)) { 158 if (net_ratelimit()) 159 netdev_info(netdev, 160 "%s: %s is down, dropping %d rx packets\n", 161 __func__, netdev->name, pkts); 162 netdev->stats.rx_dropped += pkts; 163 } 164 165 return ret; 166} 167 168static int es58x_fd_rx_event_msg(struct net_device *netdev, 169 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 170{ 171 struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev; 172 u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 173 const struct es58x_fd_rx_event_msg *rx_event_msg; 174 int ret; 175 176 rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg; 177 ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len); 178 if (ret) 179 return ret; 180 181 return es58x_rx_err_msg(netdev, rx_event_msg->error_code, 182 rx_event_msg->event_code, 183 get_unaligned_le64(&rx_event_msg->timestamp)); 184} 185 186static int es58x_fd_rx_cmd_ret_u32(struct net_device *netdev, 187 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd, 188 enum es58x_ret_type cmd_ret_type) 189{ 190 struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev; 191 u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 192 int ret; 193 194 ret = es58x_check_msg_len(es58x_dev->dev, 195 es58x_fd_urb_cmd->rx_cmd_ret_le32, msg_len); 196 if (ret) 197 return ret; 198 199 return es58x_rx_cmd_ret_u32(netdev, cmd_ret_type, 200 get_unaligned_le32(&es58x_fd_urb_cmd->rx_cmd_ret_le32)); 201} 202 203static int es58x_fd_tx_ack_msg(struct net_device *netdev, 204 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 205{ 206 struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev; 207 const struct es58x_fd_tx_ack_msg *tx_ack_msg; 208 u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 209 int ret; 210 211 tx_ack_msg = &es58x_fd_urb_cmd->tx_ack_msg; 212 ret = es58x_check_msg_len(es58x_dev->dev, *tx_ack_msg, msg_len); 213 if (ret) 214 return ret; 215 216 return es58x_tx_ack_msg(netdev, 217 get_unaligned_le16(&tx_ack_msg->tx_free_entries), 218 get_unaligned_le32(&tx_ack_msg->rx_cmd_ret_le32)); 219} 220 221static int es58x_fd_can_cmd_id(struct es58x_device *es58x_dev, 222 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 223{ 224 struct net_device *netdev; 225 int ret; 226 227 ret = es58x_get_netdev(es58x_dev, es58x_fd_urb_cmd->channel_idx, 228 ES58X_FD_CHANNEL_IDX_OFFSET, &netdev); 229 if (ret) 230 return ret; 231 232 switch ((enum es58x_fd_can_cmd_id)es58x_fd_urb_cmd->cmd_id) { 233 case ES58X_FD_CAN_CMD_ID_ENABLE_CHANNEL: 234 return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd, 235 ES58X_RET_TYPE_ENABLE_CHANNEL); 236 237 case ES58X_FD_CAN_CMD_ID_DISABLE_CHANNEL: 238 return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd, 239 ES58X_RET_TYPE_DISABLE_CHANNEL); 240 241 case ES58X_FD_CAN_CMD_ID_TX_MSG: 242 return es58x_fd_tx_ack_msg(netdev, es58x_fd_urb_cmd); 243 244 case ES58X_FD_CAN_CMD_ID_ECHO_MSG: 245 return es58x_fd_echo_msg(netdev, es58x_fd_urb_cmd); 246 247 case ES58X_FD_CAN_CMD_ID_RX_MSG: 248 return es58x_fd_rx_can_msg(netdev, es58x_fd_urb_cmd); 249 250 case ES58X_FD_CAN_CMD_ID_RESET_RX: 251 return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd, 252 ES58X_RET_TYPE_RESET_RX); 253 254 case ES58X_FD_CAN_CMD_ID_RESET_TX: 255 return es58x_fd_rx_cmd_ret_u32(netdev, es58x_fd_urb_cmd, 256 ES58X_RET_TYPE_RESET_TX); 257 258 case ES58X_FD_CAN_CMD_ID_ERROR_OR_EVENT_MSG: 259 return es58x_fd_rx_event_msg(netdev, es58x_fd_urb_cmd); 260 261 default: 262 return -EBADRQC; 263 } 264} 265 266static int es58x_fd_device_cmd_id(struct es58x_device *es58x_dev, 267 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd) 268{ 269 u16 msg_len = get_unaligned_le16(&es58x_fd_urb_cmd->msg_len); 270 int ret; 271 272 switch ((enum es58x_fd_dev_cmd_id)es58x_fd_urb_cmd->cmd_id) { 273 case ES58X_FD_DEV_CMD_ID_TIMESTAMP: 274 ret = es58x_check_msg_len(es58x_dev->dev, 275 es58x_fd_urb_cmd->timestamp, msg_len); 276 if (ret) 277 return ret; 278 es58x_rx_timestamp(es58x_dev, 279 get_unaligned_le64(&es58x_fd_urb_cmd->timestamp)); 280 return 0; 281 282 default: 283 return -EBADRQC; 284 } 285} 286 287static int es58x_fd_handle_urb_cmd(struct es58x_device *es58x_dev, 288 const union es58x_urb_cmd *urb_cmd) 289{ 290 const struct es58x_fd_urb_cmd *es58x_fd_urb_cmd; 291 int ret; 292 293 es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd; 294 295 switch ((enum es58x_fd_cmd_type)es58x_fd_urb_cmd->cmd_type) { 296 case ES58X_FD_CMD_TYPE_CAN: 297 case ES58X_FD_CMD_TYPE_CANFD: 298 ret = es58x_fd_can_cmd_id(es58x_dev, es58x_fd_urb_cmd); 299 break; 300 301 case ES58X_FD_CMD_TYPE_DEVICE: 302 ret = es58x_fd_device_cmd_id(es58x_dev, es58x_fd_urb_cmd); 303 break; 304 305 default: 306 ret = -EBADRQC; 307 break; 308 } 309 310 if (ret == -EBADRQC) 311 dev_err(es58x_dev->dev, 312 "%s: Unknown command type (0x%02X) and command ID (0x%02X) combination\n", 313 __func__, es58x_fd_urb_cmd->cmd_type, 314 es58x_fd_urb_cmd->cmd_id); 315 316 return ret; 317} 318 319static void es58x_fd_fill_urb_header(union es58x_urb_cmd *urb_cmd, u8 cmd_type, 320 u8 cmd_id, u8 channel_idx, u16 msg_len) 321{ 322 struct es58x_fd_urb_cmd *es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd; 323 324 es58x_fd_urb_cmd->SOF = cpu_to_le16(es58x_fd_param.tx_start_of_frame); 325 es58x_fd_urb_cmd->cmd_type = cmd_type; 326 es58x_fd_urb_cmd->cmd_id = cmd_id; 327 es58x_fd_urb_cmd->channel_idx = channel_idx; 328 es58x_fd_urb_cmd->msg_len = cpu_to_le16(msg_len); 329} 330 331static int es58x_fd_tx_can_msg(struct es58x_priv *priv, 332 const struct sk_buff *skb) 333{ 334 struct es58x_device *es58x_dev = priv->es58x_dev; 335 union es58x_urb_cmd *urb_cmd = priv->tx_urb->transfer_buffer; 336 struct es58x_fd_urb_cmd *es58x_fd_urb_cmd = &urb_cmd->es58x_fd_urb_cmd; 337 struct can_frame *cf = (struct can_frame *)skb->data; 338 struct es58x_fd_tx_can_msg *tx_can_msg; 339 bool is_fd = can_is_canfd_skb(skb); 340 u16 msg_len; 341 int ret; 342 343 if (priv->tx_can_msg_cnt == 0) { 344 msg_len = 0; 345 es58x_fd_fill_urb_header(urb_cmd, 346 is_fd ? ES58X_FD_CMD_TYPE_CANFD 347 : ES58X_FD_CMD_TYPE_CAN, 348 ES58X_FD_CAN_CMD_ID_TX_MSG_NO_ACK, 349 priv->channel_idx, msg_len); 350 } else { 351 msg_len = es58x_fd_get_msg_len(urb_cmd); 352 } 353 354 ret = es58x_check_msg_max_len(es58x_dev->dev, 355 es58x_fd_urb_cmd->tx_can_msg_buf, 356 msg_len + sizeof(*tx_can_msg)); 357 if (ret) 358 return ret; 359 360 /* Fill message contents. */ 361 tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len]; 362 tx_can_msg->packet_idx = (u8)priv->tx_head; 363 put_unaligned_le32(es58x_get_raw_can_id(cf), &tx_can_msg->can_id); 364 tx_can_msg->flags = (u8)es58x_get_flags(skb); 365 if (is_fd) 366 tx_can_msg->len = cf->len; 367 else 368 tx_can_msg->dlc = can_get_cc_dlc(cf, priv->can.ctrlmode); 369 memcpy(tx_can_msg->data, cf->data, cf->len); 370 371 /* Calculate new sizes */ 372 msg_len += es58x_fd_sizeof_rx_tx_msg(*tx_can_msg); 373 priv->tx_urb->transfer_buffer_length = es58x_get_urb_cmd_len(es58x_dev, 374 msg_len); 375 put_unaligned_le16(msg_len, &es58x_fd_urb_cmd->msg_len); 376 377 return 0; 378} 379 380static void es58x_fd_convert_bittiming(struct es58x_fd_bittiming *es58x_fd_bt, 381 struct can_bittiming *bt) 382{ 383 /* The actual value set in the hardware registers is one less 384 * than the functional value. 385 */ 386 const int offset = 1; 387 388 es58x_fd_bt->bitrate = cpu_to_le32(bt->bitrate); 389 es58x_fd_bt->tseg1 = 390 cpu_to_le16(bt->prop_seg + bt->phase_seg1 - offset); 391 es58x_fd_bt->tseg2 = cpu_to_le16(bt->phase_seg2 - offset); 392 es58x_fd_bt->brp = cpu_to_le16(bt->brp - offset); 393 es58x_fd_bt->sjw = cpu_to_le16(bt->sjw - offset); 394} 395 396static int es58x_fd_enable_channel(struct es58x_priv *priv) 397{ 398 struct es58x_device *es58x_dev = priv->es58x_dev; 399 struct net_device *netdev = es58x_dev->netdev[priv->channel_idx]; 400 struct es58x_fd_tx_conf_msg tx_conf_msg = { 0 }; 401 u32 ctrlmode; 402 size_t conf_len = 0; 403 404 es58x_fd_convert_bittiming(&tx_conf_msg.nominal_bittiming, 405 &priv->can.bittiming); 406 ctrlmode = priv->can.ctrlmode; 407 408 if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) 409 tx_conf_msg.samples_per_bit = ES58X_SAMPLES_PER_BIT_THREE; 410 else 411 tx_conf_msg.samples_per_bit = ES58X_SAMPLES_PER_BIT_ONE; 412 tx_conf_msg.sync_edge = ES58X_SYNC_EDGE_SINGLE; 413 tx_conf_msg.physical_layer = ES58X_PHYSICAL_LAYER_HIGH_SPEED; 414 tx_conf_msg.echo_mode = ES58X_ECHO_ON; 415 if (ctrlmode & CAN_CTRLMODE_LISTENONLY) 416 tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_PASSIVE; 417 else 418 tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_ACTIVE; 419 420 if (ctrlmode & CAN_CTRLMODE_FD_NON_ISO) { 421 tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_FD_NON_ISO; 422 tx_conf_msg.canfd_enabled = 1; 423 } else if (ctrlmode & CAN_CTRLMODE_FD) { 424 tx_conf_msg.ctrlmode |= ES58X_FD_CTRLMODE_FD; 425 tx_conf_msg.canfd_enabled = 1; 426 } 427 428 if (tx_conf_msg.canfd_enabled) { 429 es58x_fd_convert_bittiming(&tx_conf_msg.data_bittiming, 430 &priv->can.data_bittiming); 431 432 if (can_tdc_is_enabled(&priv->can)) { 433 tx_conf_msg.tdc_enabled = 1; 434 tx_conf_msg.tdco = cpu_to_le16(priv->can.tdc.tdco); 435 tx_conf_msg.tdcf = cpu_to_le16(priv->can.tdc.tdcf); 436 } 437 438 conf_len = ES58X_FD_CANFD_CONF_LEN; 439 } else { 440 conf_len = ES58X_FD_CAN_CONF_LEN; 441 } 442 443 return es58x_send_msg(es58x_dev, es58x_fd_cmd_type(netdev), 444 ES58X_FD_CAN_CMD_ID_ENABLE_CHANNEL, 445 &tx_conf_msg, conf_len, priv->channel_idx); 446} 447 448static int es58x_fd_disable_channel(struct es58x_priv *priv) 449{ 450 /* The type (ES58X_FD_CMD_TYPE_CAN or ES58X_FD_CMD_TYPE_CANFD) does 451 * not matter here. 452 */ 453 return es58x_send_msg(priv->es58x_dev, ES58X_FD_CMD_TYPE_CAN, 454 ES58X_FD_CAN_CMD_ID_DISABLE_CHANNEL, 455 ES58X_EMPTY_MSG, 0, priv->channel_idx); 456} 457 458static int es58x_fd_get_timestamp(struct es58x_device *es58x_dev) 459{ 460 return es58x_send_msg(es58x_dev, ES58X_FD_CMD_TYPE_DEVICE, 461 ES58X_FD_DEV_CMD_ID_TIMESTAMP, ES58X_EMPTY_MSG, 462 0, ES58X_CHANNEL_IDX_NA); 463} 464 465/* Nominal bittiming constants for ES582.1 and ES584.1 as specified in 466 * the microcontroller datasheet: "SAM E70/S70/V70/V71 Family" section 467 * 49.6.8 "MCAN Nominal Bit Timing and Prescaler Register" from 468 * Microchip. 469 * 470 * The values from the specification are the hardware register 471 * values. To convert them to the functional values, all ranges were 472 * incremented by 1 (e.g. range [0..n-1] changed to [1..n]). 473 */ 474static const struct can_bittiming_const es58x_fd_nom_bittiming_const = { 475 .name = "ES582.1/ES584.1", 476 .tseg1_min = 2, 477 .tseg1_max = 256, 478 .tseg2_min = 2, 479 .tseg2_max = 128, 480 .sjw_max = 128, 481 .brp_min = 1, 482 .brp_max = 512, 483 .brp_inc = 1 484}; 485 486/* Data bittiming constants for ES582.1 and ES584.1 as specified in 487 * the microcontroller datasheet: "SAM E70/S70/V70/V71 Family" section 488 * 49.6.4 "MCAN Data Bit Timing and Prescaler Register" from 489 * Microchip. 490 */ 491static const struct can_bittiming_const es58x_fd_data_bittiming_const = { 492 .name = "ES582.1/ES584.1", 493 .tseg1_min = 2, 494 .tseg1_max = 32, 495 .tseg2_min = 1, 496 .tseg2_max = 16, 497 .sjw_max = 8, 498 .brp_min = 1, 499 .brp_max = 32, 500 .brp_inc = 1 501}; 502 503/* Transmission Delay Compensation constants for ES582.1 and ES584.1 504 * as specified in the microcontroller datasheet: "SAM E70/S70/V70/V71 505 * Family" section 49.6.15 "MCAN Transmitter Delay Compensation 506 * Register" from Microchip. 507 */ 508static const struct can_tdc_const es58x_tdc_const = { 509 .tdcv_min = 0, 510 .tdcv_max = 0, /* Manual mode not supported. */ 511 .tdco_min = 0, 512 .tdco_max = 127, 513 .tdcf_min = 0, 514 .tdcf_max = 127 515}; 516 517const struct es58x_parameters es58x_fd_param = { 518 .bittiming_const = &es58x_fd_nom_bittiming_const, 519 .data_bittiming_const = &es58x_fd_data_bittiming_const, 520 .tdc_const = &es58x_tdc_const, 521 /* The devices use NXP TJA1044G transievers which guarantee 522 * the timing for data rates up to 5 Mbps. Bitrates up to 8 523 * Mbps work in an optimal environment but are not recommended 524 * for production environment. 525 */ 526 .bitrate_max = 8 * MEGA /* BPS */, 527 .clock = {.freq = 80 * MEGA /* Hz */}, 528 .ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | 529 CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO | 530 CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_TDC_AUTO, 531 .tx_start_of_frame = 0xCEFA, /* FACE in little endian */ 532 .rx_start_of_frame = 0xFECA, /* CAFE in little endian */ 533 .tx_urb_cmd_max_len = ES58X_FD_TX_URB_CMD_MAX_LEN, 534 .rx_urb_cmd_max_len = ES58X_FD_RX_URB_CMD_MAX_LEN, 535 /* Size of internal device TX queue is 500. 536 * 537 * However, when reaching value around 278, the device's busy 538 * LED turns on and thus maximum value of 500 is never reached 539 * in practice. Also, when this value is too high, some error 540 * on the echo_msg were witnessed when the device is 541 * recovering from bus off. 542 * 543 * For above reasons, a value that would prevent the device 544 * from becoming busy was chosen. In practice, BQL would 545 * prevent the value from even getting closer to below 546 * maximum, so no impact on performance was measured. 547 */ 548 .fifo_mask = 255, /* echo_skb_max = 256 */ 549 .dql_min_limit = CAN_FRAME_LEN_MAX * 15, /* Empirical value. */ 550 .tx_bulk_max = ES58X_FD_TX_BULK_MAX, 551 .urb_cmd_header_len = ES58X_FD_URB_CMD_HEADER_LEN, 552 .rx_urb_max = ES58X_RX_URBS_MAX, 553 .tx_urb_max = ES58X_TX_URBS_MAX 554}; 555 556const struct es58x_operators es58x_fd_ops = { 557 .get_msg_len = es58x_fd_get_msg_len, 558 .handle_urb_cmd = es58x_fd_handle_urb_cmd, 559 .fill_urb_header = es58x_fd_fill_urb_header, 560 .tx_can_msg = es58x_fd_tx_can_msg, 561 .enable_channel = es58x_fd_enable_channel, 562 .disable_channel = es58x_fd_disable_channel, 563 .reset_device = NULL, /* Not implemented in the device firmware. */ 564 .get_timestamp = es58x_fd_get_timestamp 565};