0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/units.h>
0014 #include <asm/unaligned.h>
0015
0016 #include "es58x_core.h"
0017 #include "es581_4.h"
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #define es581_4_sizeof_rx_tx_msg(msg) \
0032 offsetof(typeof(msg), data[can_cc_dlc2len((msg).dlc)])
0033
0034 static u16 es581_4_get_msg_len(const union es58x_urb_cmd *urb_cmd)
0035 {
0036 return get_unaligned_le16(&urb_cmd->es581_4_urb_cmd.msg_len);
0037 }
0038
0039 static int es581_4_echo_msg(struct es58x_device *es58x_dev,
0040 const struct es581_4_urb_cmd *es581_4_urb_cmd)
0041 {
0042 struct net_device *netdev;
0043 const struct es581_4_bulk_echo_msg *bulk_echo_msg;
0044 const struct es581_4_echo_msg *echo_msg;
0045 u64 *tstamps = es58x_dev->timestamps;
0046 u16 msg_len;
0047 u32 first_packet_idx, packet_idx;
0048 unsigned int dropped = 0;
0049 int i, num_element, ret;
0050
0051 bulk_echo_msg = &es581_4_urb_cmd->bulk_echo_msg;
0052 msg_len = get_unaligned_le16(&es581_4_urb_cmd->msg_len) -
0053 sizeof(bulk_echo_msg->channel_no);
0054 num_element = es58x_msg_num_element(es58x_dev->dev,
0055 bulk_echo_msg->echo_msg, msg_len);
0056 if (num_element <= 0)
0057 return num_element;
0058
0059 ret = es58x_get_netdev(es58x_dev, bulk_echo_msg->channel_no,
0060 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0061 if (ret)
0062 return ret;
0063
0064 echo_msg = &bulk_echo_msg->echo_msg[0];
0065 first_packet_idx = get_unaligned_le32(&echo_msg->packet_idx);
0066 packet_idx = first_packet_idx;
0067 for (i = 0; i < num_element; i++) {
0068 u32 tmp_idx;
0069
0070 echo_msg = &bulk_echo_msg->echo_msg[i];
0071 tmp_idx = get_unaligned_le32(&echo_msg->packet_idx);
0072 if (tmp_idx == packet_idx - 1) {
0073 if (net_ratelimit())
0074 netdev_warn(netdev,
0075 "Received echo packet idx %u twice\n",
0076 packet_idx - 1);
0077 dropped++;
0078 continue;
0079 }
0080 if (tmp_idx != packet_idx) {
0081 netdev_err(netdev, "Echo packet idx jumped from %u to %u\n",
0082 packet_idx - 1, echo_msg->packet_idx);
0083 return -EBADMSG;
0084 }
0085
0086 tstamps[i] = get_unaligned_le64(&echo_msg->timestamp);
0087 packet_idx++;
0088 }
0089
0090 netdev->stats.tx_dropped += dropped;
0091 return es58x_can_get_echo_skb(netdev, first_packet_idx,
0092 tstamps, num_element - dropped);
0093 }
0094
0095 static int es581_4_rx_can_msg(struct es58x_device *es58x_dev,
0096 const struct es581_4_urb_cmd *es581_4_urb_cmd,
0097 u16 msg_len)
0098 {
0099 const struct device *dev = es58x_dev->dev;
0100 struct net_device *netdev;
0101 int pkts, num_element, channel_no, ret;
0102
0103 num_element = es58x_msg_num_element(dev, es581_4_urb_cmd->rx_can_msg,
0104 msg_len);
0105 if (num_element <= 0)
0106 return num_element;
0107
0108 channel_no = es581_4_urb_cmd->rx_can_msg[0].channel_no;
0109 ret = es58x_get_netdev(es58x_dev, channel_no,
0110 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0111 if (ret)
0112 return ret;
0113
0114 if (!netif_running(netdev)) {
0115 if (net_ratelimit())
0116 netdev_info(netdev,
0117 "%s: %s is down, dropping %d rx packets\n",
0118 __func__, netdev->name, num_element);
0119 netdev->stats.rx_dropped += num_element;
0120 return 0;
0121 }
0122
0123 for (pkts = 0; pkts < num_element; pkts++) {
0124 const struct es581_4_rx_can_msg *rx_can_msg =
0125 &es581_4_urb_cmd->rx_can_msg[pkts];
0126 u64 tstamp = get_unaligned_le64(&rx_can_msg->timestamp);
0127 canid_t can_id = get_unaligned_le32(&rx_can_msg->can_id);
0128
0129 if (channel_no != rx_can_msg->channel_no)
0130 return -EBADMSG;
0131
0132 ret = es58x_rx_can_msg(netdev, tstamp, rx_can_msg->data,
0133 can_id, rx_can_msg->flags,
0134 rx_can_msg->dlc);
0135 if (ret)
0136 break;
0137 }
0138
0139 return ret;
0140 }
0141
0142 static int es581_4_rx_err_msg(struct es58x_device *es58x_dev,
0143 const struct es581_4_rx_err_msg *rx_err_msg)
0144 {
0145 struct net_device *netdev;
0146 enum es58x_err error = get_unaligned_le32(&rx_err_msg->error);
0147 int ret;
0148
0149 ret = es58x_get_netdev(es58x_dev, rx_err_msg->channel_no,
0150 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0151 if (ret)
0152 return ret;
0153
0154 return es58x_rx_err_msg(netdev, error, 0,
0155 get_unaligned_le64(&rx_err_msg->timestamp));
0156 }
0157
0158 static int es581_4_rx_event_msg(struct es58x_device *es58x_dev,
0159 const struct es581_4_rx_event_msg *rx_event_msg)
0160 {
0161 struct net_device *netdev;
0162 enum es58x_event event = get_unaligned_le32(&rx_event_msg->event);
0163 int ret;
0164
0165 ret = es58x_get_netdev(es58x_dev, rx_event_msg->channel_no,
0166 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0167 if (ret)
0168 return ret;
0169
0170 return es58x_rx_err_msg(netdev, 0, event,
0171 get_unaligned_le64(&rx_event_msg->timestamp));
0172 }
0173
0174 static int es581_4_rx_cmd_ret_u32(struct es58x_device *es58x_dev,
0175 const struct es581_4_urb_cmd *es581_4_urb_cmd,
0176 enum es58x_ret_type ret_type)
0177 {
0178 struct net_device *netdev;
0179 const struct es581_4_rx_cmd_ret *rx_cmd_ret;
0180 u16 msg_len = get_unaligned_le16(&es581_4_urb_cmd->msg_len);
0181 int ret;
0182
0183 ret = es58x_check_msg_len(es58x_dev->dev,
0184 es581_4_urb_cmd->rx_cmd_ret, msg_len);
0185 if (ret)
0186 return ret;
0187
0188 rx_cmd_ret = &es581_4_urb_cmd->rx_cmd_ret;
0189
0190 ret = es58x_get_netdev(es58x_dev, rx_cmd_ret->channel_no,
0191 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0192 if (ret)
0193 return ret;
0194
0195 return es58x_rx_cmd_ret_u32(netdev, ret_type,
0196 get_unaligned_le32(&rx_cmd_ret->rx_cmd_ret_le32));
0197 }
0198
0199 static int es581_4_tx_ack_msg(struct es58x_device *es58x_dev,
0200 const struct es581_4_urb_cmd *es581_4_urb_cmd)
0201 {
0202 struct net_device *netdev;
0203 const struct es581_4_tx_ack_msg *tx_ack_msg;
0204 u16 msg_len = get_unaligned_le16(&es581_4_urb_cmd->msg_len);
0205 int ret;
0206
0207 tx_ack_msg = &es581_4_urb_cmd->tx_ack_msg;
0208 ret = es58x_check_msg_len(es58x_dev->dev, *tx_ack_msg, msg_len);
0209 if (ret)
0210 return ret;
0211
0212 if (tx_ack_msg->rx_cmd_ret_u8 != ES58X_RET_U8_OK)
0213 return es58x_rx_cmd_ret_u8(es58x_dev->dev,
0214 ES58X_RET_TYPE_TX_MSG,
0215 tx_ack_msg->rx_cmd_ret_u8);
0216
0217 ret = es58x_get_netdev(es58x_dev, tx_ack_msg->channel_no,
0218 ES581_4_CHANNEL_IDX_OFFSET, &netdev);
0219 if (ret)
0220 return ret;
0221
0222 return es58x_tx_ack_msg(netdev,
0223 get_unaligned_le16(&tx_ack_msg->tx_free_entries),
0224 ES58X_RET_U32_OK);
0225 }
0226
0227 static int es581_4_dispatch_rx_cmd(struct es58x_device *es58x_dev,
0228 const struct es581_4_urb_cmd *es581_4_urb_cmd)
0229 {
0230 const struct device *dev = es58x_dev->dev;
0231 u16 msg_len = get_unaligned_le16(&es581_4_urb_cmd->msg_len);
0232 enum es581_4_rx_type rx_type = es581_4_urb_cmd->rx_can_msg[0].rx_type;
0233 int ret = 0;
0234
0235 switch (rx_type) {
0236 case ES581_4_RX_TYPE_MESSAGE:
0237 return es581_4_rx_can_msg(es58x_dev, es581_4_urb_cmd, msg_len);
0238
0239 case ES581_4_RX_TYPE_ERROR:
0240 ret = es58x_check_msg_len(dev, es581_4_urb_cmd->rx_err_msg,
0241 msg_len);
0242 if (ret < 0)
0243 return ret;
0244 return es581_4_rx_err_msg(es58x_dev,
0245 &es581_4_urb_cmd->rx_err_msg);
0246
0247 case ES581_4_RX_TYPE_EVENT:
0248 ret = es58x_check_msg_len(dev, es581_4_urb_cmd->rx_event_msg,
0249 msg_len);
0250 if (ret < 0)
0251 return ret;
0252 return es581_4_rx_event_msg(es58x_dev,
0253 &es581_4_urb_cmd->rx_event_msg);
0254
0255 default:
0256 dev_err(dev, "%s: Unknown rx_type 0x%02X\n", __func__, rx_type);
0257 return -EBADRQC;
0258 }
0259 }
0260
0261 static int es581_4_handle_urb_cmd(struct es58x_device *es58x_dev,
0262 const union es58x_urb_cmd *urb_cmd)
0263 {
0264 const struct es581_4_urb_cmd *es581_4_urb_cmd;
0265 struct device *dev = es58x_dev->dev;
0266 u16 msg_len = es581_4_get_msg_len(urb_cmd);
0267 int ret;
0268
0269 es581_4_urb_cmd = &urb_cmd->es581_4_urb_cmd;
0270
0271 if (es581_4_urb_cmd->cmd_type != ES581_4_CAN_COMMAND_TYPE) {
0272 dev_err(dev, "%s: Unknown command type (0x%02X)\n",
0273 __func__, es581_4_urb_cmd->cmd_type);
0274 return -EBADRQC;
0275 }
0276
0277 switch ((enum es581_4_cmd_id)es581_4_urb_cmd->cmd_id) {
0278 case ES581_4_CMD_ID_SET_BITTIMING:
0279 return es581_4_rx_cmd_ret_u32(es58x_dev, es581_4_urb_cmd,
0280 ES58X_RET_TYPE_SET_BITTIMING);
0281
0282 case ES581_4_CMD_ID_ENABLE_CHANNEL:
0283 return es581_4_rx_cmd_ret_u32(es58x_dev, es581_4_urb_cmd,
0284 ES58X_RET_TYPE_ENABLE_CHANNEL);
0285
0286 case ES581_4_CMD_ID_TX_MSG:
0287 return es581_4_tx_ack_msg(es58x_dev, es581_4_urb_cmd);
0288
0289 case ES581_4_CMD_ID_RX_MSG:
0290 return es581_4_dispatch_rx_cmd(es58x_dev, es581_4_urb_cmd);
0291
0292 case ES581_4_CMD_ID_RESET_RX:
0293 ret = es581_4_rx_cmd_ret_u32(es58x_dev, es581_4_urb_cmd,
0294 ES58X_RET_TYPE_RESET_RX);
0295 return ret;
0296
0297 case ES581_4_CMD_ID_RESET_TX:
0298 ret = es581_4_rx_cmd_ret_u32(es58x_dev, es581_4_urb_cmd,
0299 ES58X_RET_TYPE_RESET_TX);
0300 return ret;
0301
0302 case ES581_4_CMD_ID_DISABLE_CHANNEL:
0303 return es581_4_rx_cmd_ret_u32(es58x_dev, es581_4_urb_cmd,
0304 ES58X_RET_TYPE_DISABLE_CHANNEL);
0305
0306 case ES581_4_CMD_ID_TIMESTAMP:
0307 ret = es58x_check_msg_len(dev, es581_4_urb_cmd->timestamp,
0308 msg_len);
0309 if (ret < 0)
0310 return ret;
0311 es58x_rx_timestamp(es58x_dev,
0312 get_unaligned_le64(&es581_4_urb_cmd->timestamp));
0313 return 0;
0314
0315 case ES581_4_CMD_ID_ECHO:
0316 return es581_4_echo_msg(es58x_dev, es581_4_urb_cmd);
0317
0318 case ES581_4_CMD_ID_DEVICE_ERR:
0319 ret = es58x_check_msg_len(dev, es581_4_urb_cmd->rx_cmd_ret_u8,
0320 msg_len);
0321 if (ret)
0322 return ret;
0323 return es58x_rx_cmd_ret_u8(dev, ES58X_RET_TYPE_DEVICE_ERR,
0324 es581_4_urb_cmd->rx_cmd_ret_u8);
0325
0326 default:
0327 dev_warn(dev, "%s: Unexpected command ID: 0x%02X\n",
0328 __func__, es581_4_urb_cmd->cmd_id);
0329 return -EBADRQC;
0330 }
0331 }
0332
0333 static void es581_4_fill_urb_header(union es58x_urb_cmd *urb_cmd, u8 cmd_type,
0334 u8 cmd_id, u8 channel_idx, u16 msg_len)
0335 {
0336 struct es581_4_urb_cmd *es581_4_urb_cmd = &urb_cmd->es581_4_urb_cmd;
0337
0338 es581_4_urb_cmd->SOF = cpu_to_le16(es581_4_param.tx_start_of_frame);
0339 es581_4_urb_cmd->cmd_type = cmd_type;
0340 es581_4_urb_cmd->cmd_id = cmd_id;
0341 es581_4_urb_cmd->msg_len = cpu_to_le16(msg_len);
0342 }
0343
0344 static int es581_4_tx_can_msg(struct es58x_priv *priv,
0345 const struct sk_buff *skb)
0346 {
0347 struct es58x_device *es58x_dev = priv->es58x_dev;
0348 union es58x_urb_cmd *urb_cmd = priv->tx_urb->transfer_buffer;
0349 struct es581_4_urb_cmd *es581_4_urb_cmd = &urb_cmd->es581_4_urb_cmd;
0350 struct can_frame *cf = (struct can_frame *)skb->data;
0351 struct es581_4_tx_can_msg *tx_can_msg;
0352 u16 msg_len;
0353 int ret;
0354
0355 if (can_is_canfd_skb(skb))
0356 return -EMSGSIZE;
0357
0358 if (priv->tx_can_msg_cnt == 0) {
0359 msg_len = sizeof(es581_4_urb_cmd->bulk_tx_can_msg.num_can_msg);
0360 es581_4_fill_urb_header(urb_cmd, ES581_4_CAN_COMMAND_TYPE,
0361 ES581_4_CMD_ID_TX_MSG,
0362 priv->channel_idx, msg_len);
0363 es581_4_urb_cmd->bulk_tx_can_msg.num_can_msg = 0;
0364 } else {
0365 msg_len = es581_4_get_msg_len(urb_cmd);
0366 }
0367
0368 ret = es58x_check_msg_max_len(es58x_dev->dev,
0369 es581_4_urb_cmd->bulk_tx_can_msg,
0370 msg_len + sizeof(*tx_can_msg));
0371 if (ret)
0372 return ret;
0373
0374
0375 tx_can_msg = (typeof(tx_can_msg))&es581_4_urb_cmd->raw_msg[msg_len];
0376 put_unaligned_le32(es58x_get_raw_can_id(cf), &tx_can_msg->can_id);
0377 put_unaligned_le32(priv->tx_head, &tx_can_msg->packet_idx);
0378 put_unaligned_le16((u16)es58x_get_flags(skb), &tx_can_msg->flags);
0379 tx_can_msg->channel_no = priv->channel_idx + ES581_4_CHANNEL_IDX_OFFSET;
0380 tx_can_msg->dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
0381
0382 memcpy(tx_can_msg->data, cf->data, cf->len);
0383
0384
0385 es581_4_urb_cmd->bulk_tx_can_msg.num_can_msg++;
0386 msg_len += es581_4_sizeof_rx_tx_msg(*tx_can_msg);
0387 priv->tx_urb->transfer_buffer_length = es58x_get_urb_cmd_len(es58x_dev,
0388 msg_len);
0389 es581_4_urb_cmd->msg_len = cpu_to_le16(msg_len);
0390
0391 return 0;
0392 }
0393
0394 static int es581_4_set_bittiming(struct es58x_priv *priv)
0395 {
0396 struct es581_4_tx_conf_msg tx_conf_msg = { 0 };
0397 struct can_bittiming *bt = &priv->can.bittiming;
0398
0399 tx_conf_msg.bitrate = cpu_to_le32(bt->bitrate);
0400
0401 tx_conf_msg.sample_point = cpu_to_le32(bt->sample_point / 10U);
0402 tx_conf_msg.samples_per_bit = cpu_to_le32(ES58X_SAMPLES_PER_BIT_ONE);
0403 tx_conf_msg.bit_time = cpu_to_le32(can_bit_time(bt));
0404 tx_conf_msg.sjw = cpu_to_le32(bt->sjw);
0405 tx_conf_msg.sync_edge = cpu_to_le32(ES58X_SYNC_EDGE_SINGLE);
0406 tx_conf_msg.physical_layer =
0407 cpu_to_le32(ES58X_PHYSICAL_LAYER_HIGH_SPEED);
0408 tx_conf_msg.echo_mode = cpu_to_le32(ES58X_ECHO_ON);
0409 tx_conf_msg.channel_no = priv->channel_idx + ES581_4_CHANNEL_IDX_OFFSET;
0410
0411 return es58x_send_msg(priv->es58x_dev, ES581_4_CAN_COMMAND_TYPE,
0412 ES581_4_CMD_ID_SET_BITTIMING, &tx_conf_msg,
0413 sizeof(tx_conf_msg), priv->channel_idx);
0414 }
0415
0416 static int es581_4_enable_channel(struct es58x_priv *priv)
0417 {
0418 int ret;
0419 u8 msg = priv->channel_idx + ES581_4_CHANNEL_IDX_OFFSET;
0420
0421 ret = es581_4_set_bittiming(priv);
0422 if (ret)
0423 return ret;
0424
0425 return es58x_send_msg(priv->es58x_dev, ES581_4_CAN_COMMAND_TYPE,
0426 ES581_4_CMD_ID_ENABLE_CHANNEL, &msg, sizeof(msg),
0427 priv->channel_idx);
0428 }
0429
0430 static int es581_4_disable_channel(struct es58x_priv *priv)
0431 {
0432 u8 msg = priv->channel_idx + ES581_4_CHANNEL_IDX_OFFSET;
0433
0434 return es58x_send_msg(priv->es58x_dev, ES581_4_CAN_COMMAND_TYPE,
0435 ES581_4_CMD_ID_DISABLE_CHANNEL, &msg, sizeof(msg),
0436 priv->channel_idx);
0437 }
0438
0439 static int es581_4_reset_device(struct es58x_device *es58x_dev)
0440 {
0441 return es58x_send_msg(es58x_dev, ES581_4_CAN_COMMAND_TYPE,
0442 ES581_4_CMD_ID_RESET_DEVICE,
0443 ES58X_EMPTY_MSG, 0, ES58X_CHANNEL_IDX_NA);
0444 }
0445
0446 static int es581_4_get_timestamp(struct es58x_device *es58x_dev)
0447 {
0448 return es58x_send_msg(es58x_dev, ES581_4_CAN_COMMAND_TYPE,
0449 ES581_4_CMD_ID_TIMESTAMP,
0450 ES58X_EMPTY_MSG, 0, ES58X_CHANNEL_IDX_NA);
0451 }
0452
0453
0454
0455
0456
0457 static const struct can_bittiming_const es581_4_bittiming_const = {
0458 .name = "ES581.4",
0459 .tseg1_min = 1,
0460 .tseg1_max = 8,
0461 .tseg2_min = 1,
0462 .tseg2_max = 8,
0463 .sjw_max = 4,
0464 .brp_min = 1,
0465 .brp_max = 128,
0466 .brp_inc = 1
0467 };
0468
0469 const struct es58x_parameters es581_4_param = {
0470 .bittiming_const = &es581_4_bittiming_const,
0471 .data_bittiming_const = NULL,
0472 .tdc_const = NULL,
0473 .bitrate_max = 1 * MEGA ,
0474 .clock = {.freq = 50 * MEGA },
0475 .ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC,
0476 .tx_start_of_frame = 0xAFAF,
0477 .rx_start_of_frame = 0xFAFA,
0478 .tx_urb_cmd_max_len = ES581_4_TX_URB_CMD_MAX_LEN,
0479 .rx_urb_cmd_max_len = ES581_4_RX_URB_CMD_MAX_LEN,
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 .fifo_mask = 63,
0491 .dql_min_limit = CAN_FRAME_LEN_MAX * 50,
0492 .tx_bulk_max = ES581_4_TX_BULK_MAX,
0493 .urb_cmd_header_len = ES581_4_URB_CMD_HEADER_LEN,
0494 .rx_urb_max = ES58X_RX_URBS_MAX,
0495 .tx_urb_max = ES58X_TX_URBS_MAX
0496 };
0497
0498 const struct es58x_operators es581_4_ops = {
0499 .get_msg_len = es581_4_get_msg_len,
0500 .handle_urb_cmd = es581_4_handle_urb_cmd,
0501 .fill_urb_header = es581_4_fill_urb_header,
0502 .tx_can_msg = es581_4_tx_can_msg,
0503 .enable_channel = es581_4_enable_channel,
0504 .disable_channel = es581_4_disable_channel,
0505 .reset_device = es581_4_reset_device,
0506 .get_timestamp = es581_4_get_timestamp
0507 };