diff options
Diffstat (limited to 'drivers/net/can/usb')
-rw-r--r-- | drivers/net/can/usb/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 26 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 63 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 41 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 114 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_core.c | 3 |
6 files changed, 171 insertions, 79 deletions
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index 3e1fba12c0c3..9dae0c71a2e1 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig @@ -17,11 +17,12 @@ config CAN_EMS_USB config CAN_ESD_USB tristate "esd electronics gmbh CAN/USB interfaces" help - This driver adds supports for several CAN/USB interfaces + This driver adds support for several CAN/USB interfaces from esd electronics gmbh (https://www.esd.eu). The drivers supports the following devices: - esd CAN-USB/2 + - esd CAN-USB/3-FD - esd CAN-USB/Micro To compile this driver as a module, choose M here: the module diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h index ff10b3790d84..078496d9b7ba 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -22,6 +22,8 @@ */ #include <linux/completion.h> +#include <linux/ktime.h> +#include <linux/math64.h> #include <linux/spinlock.h> #include <linux/types.h> #include <linux/usb.h> @@ -39,7 +41,6 @@ #define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2) -#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP BIT(3) /* Device capabilities */ #define KVASER_USB_CAP_BERR_CAP 0x01 @@ -68,6 +69,7 @@ struct kvaser_usb_dev_card_data { u32 ctrlmode_supported; u32 capabilities; struct kvaser_usb_dev_card_data_hydra hydra; + u32 usbcan_timestamp_msb; }; /* Context for an outstanding, not yet ACKed, transmission */ @@ -216,4 +218,26 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev); extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const; +static inline ktime_t kvaser_usb_ticks_to_ktime(const struct kvaser_usb_dev_cfg *cfg, + u64 ticks) +{ + return ns_to_ktime(div_u64(ticks * 1000, cfg->timestamp_freq)); +} + +static inline ktime_t kvaser_usb_timestamp48_to_ktime(const struct kvaser_usb_dev_cfg *cfg, + const __le16 *timestamp) +{ + u64 ticks = le16_to_cpu(timestamp[0]) | + (u64)(le16_to_cpu(timestamp[1])) << 16 | + (u64)(le16_to_cpu(timestamp[2])) << 32; + + return kvaser_usb_ticks_to_ktime(cfg, ticks); +} + +static inline ktime_t kvaser_usb_timestamp64_to_ktime(const struct kvaser_usb_dev_cfg *cfg, + __le64 timestamp) +{ + return kvaser_usb_ticks_to_ktime(cfg, le64_to_cpu(timestamp)); +} + #endif /* KVASER_USB_H */ diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index daa34b532aa8..7d12776ab63e 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -94,7 +94,7 @@ #define USB_MINI_PCIE_1XCAN_PRODUCT_ID 0x011B static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = { - .quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP, + .quirks = 0, .ops = &kvaser_usb_hydra_dev_ops, }; @@ -756,23 +756,12 @@ freeurb: static const struct net_device_ops kvaser_usb_netdev_ops = { .ndo_open = kvaser_usb_open, .ndo_stop = kvaser_usb_close, - .ndo_start_xmit = kvaser_usb_start_xmit, - .ndo_change_mtu = can_change_mtu, -}; - -static const struct net_device_ops kvaser_usb_netdev_ops_hwts = { - .ndo_open = kvaser_usb_open, - .ndo_stop = kvaser_usb_close, .ndo_eth_ioctl = can_eth_ioctl_hwts, .ndo_start_xmit = kvaser_usb_start_xmit, .ndo_change_mtu = can_change_mtu, }; static const struct ethtool_ops kvaser_usb_ethtool_ops = { - .get_ts_info = ethtool_op_get_ts_info, -}; - -static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = { .get_ts_info = can_ethtool_op_get_ts_info_hwts, }; @@ -859,13 +848,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) netdev->flags |= IFF_ECHO; netdev->netdev_ops = &kvaser_usb_netdev_ops; - if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) { - netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts; - netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts; - } else { - netdev->netdev_ops = &kvaser_usb_netdev_ops; - netdev->ethtool_ops = &kvaser_usb_ethtool_ops; - } + netdev->ethtool_ops = &kvaser_usb_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->intf->dev); netdev->dev_id = channel; @@ -915,10 +898,8 @@ static int kvaser_usb_probe(struct usb_interface *intf, ops = driver_info->ops; err = ops->dev_setup_endpoints(dev); - if (err) { - dev_err(&intf->dev, "Cannot get usb endpoint(s)"); - return err; - } + if (err) + return dev_err_probe(&intf->dev, err, "Cannot get usb endpoint(s)"); dev->udev = interface_to_usbdev(intf); @@ -929,26 +910,20 @@ static int kvaser_usb_probe(struct usb_interface *intf, dev->card_data.ctrlmode_supported = 0; dev->card_data.capabilities = 0; err = ops->dev_init_card(dev); - if (err) { - dev_err(&intf->dev, - "Failed to initialize card, error %d\n", err); - return err; - } + if (err) + return dev_err_probe(&intf->dev, err, + "Failed to initialize card\n"); err = ops->dev_get_software_info(dev); - if (err) { - dev_err(&intf->dev, - "Cannot get software info, error %d\n", err); - return err; - } + if (err) + return dev_err_probe(&intf->dev, err, + "Cannot get software info\n"); if (ops->dev_get_software_details) { err = ops->dev_get_software_details(dev); - if (err) { - dev_err(&intf->dev, - "Cannot get software details, error %d\n", err); - return err; - } + if (err) + return dev_err_probe(&intf->dev, err, + "Cannot get software details\n"); } if (WARN_ON(!dev->cfg)) @@ -962,18 +937,16 @@ static int kvaser_usb_probe(struct usb_interface *intf, dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); err = ops->dev_get_card_info(dev); - if (err) { - dev_err(&intf->dev, "Cannot get card info, error %d\n", err); - return err; - } + if (err) + return dev_err_probe(&intf->dev, err, + "Cannot get card info\n"); if (ops->dev_get_capabilities) { err = ops->dev_get_capabilities(dev); if (err) { - dev_err(&intf->dev, - "Cannot get capabilities, error %d\n", err); kvaser_usb_remove_interfaces(dev); - return err; + return dev_err_probe(&intf->dev, err, + "Cannot get capabilities\n"); } } diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index c7ba768dfe17..3764b263add3 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -10,7 +10,6 @@ * - 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> @@ -261,6 +260,15 @@ struct kvaser_cmd_tx_can { u8 reserved[11]; } __packed; +struct kvaser_cmd_tx_ack { + __le32 id; + u8 data[8]; + u8 dlc; + u8 flags; + __le16 timestamp[3]; + u8 reserved0[8]; +} __packed; + struct kvaser_cmd_header { u8 cmd_no; /* The destination HE address is stored in 0..5 of he_addr. @@ -297,6 +305,7 @@ struct kvaser_cmd { struct kvaser_cmd_rx_can rx_can; struct kvaser_cmd_tx_can tx_can; + struct kvaser_cmd_tx_ack tx_ack; } __packed; } __packed; @@ -522,23 +531,25 @@ kvaser_usb_hydra_net_priv_from_cmd(const struct kvaser_usb *dev, return priv; } -static ktime_t -kvaser_usb_hydra_ktime_from_rx_cmd(const struct kvaser_usb_dev_cfg *cfg, - const struct kvaser_cmd *cmd) +static ktime_t kvaser_usb_hydra_ktime_from_cmd(const struct kvaser_usb_dev_cfg *cfg, + const struct kvaser_cmd *cmd) { - u64 ticks; + ktime_t hwtstamp = 0; if (cmd->header.cmd_no == CMD_EXTENDED) { struct kvaser_cmd_ext *cmd_ext = (struct kvaser_cmd_ext *)cmd; - ticks = le64_to_cpu(cmd_ext->rx_can.timestamp); - } else { - ticks = le16_to_cpu(cmd->rx_can.timestamp[0]); - ticks += (u64)(le16_to_cpu(cmd->rx_can.timestamp[1])) << 16; - ticks += (u64)(le16_to_cpu(cmd->rx_can.timestamp[2])) << 32; + if (cmd_ext->cmd_no_ext == CMD_RX_MESSAGE_FD) + hwtstamp = kvaser_usb_timestamp64_to_ktime(cfg, cmd_ext->rx_can.timestamp); + else if (cmd_ext->cmd_no_ext == CMD_TX_ACKNOWLEDGE_FD) + hwtstamp = kvaser_usb_timestamp64_to_ktime(cfg, cmd_ext->tx_ack.timestamp); + } else if (cmd->header.cmd_no == CMD_RX_MESSAGE) { + hwtstamp = kvaser_usb_timestamp48_to_ktime(cfg, cmd->rx_can.timestamp); + } else if (cmd->header.cmd_no == CMD_TX_ACKNOWLEDGE) { + hwtstamp = kvaser_usb_timestamp48_to_ktime(cfg, cmd->tx_ack.timestamp); } - return ns_to_ktime(div_u64(ticks * 1000, cfg->timestamp_freq)); + return hwtstamp; } static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev, @@ -1175,6 +1186,7 @@ static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev, bool one_shot_fail = false; bool is_err_frame = false; u16 transid = kvaser_usb_hydra_get_cmd_transid(cmd); + struct sk_buff *skb; priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd); if (!priv) @@ -1201,6 +1213,9 @@ static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev, spin_lock_irqsave(&priv->tx_contexts_lock, irq_flags); + skb = priv->can.echo_skb[context->echo_index]; + if (skb) + skb_hwtstamps(skb)->hwtstamp = kvaser_usb_hydra_ktime_from_cmd(dev->cfg, cmd); len = can_get_echo_skb(priv->netdev, context->echo_index, NULL); context->echo_index = dev->max_tx_urbs; --priv->active_tx_contexts; @@ -1234,7 +1249,7 @@ static void kvaser_usb_hydra_rx_msg_std(const struct kvaser_usb *dev, stats = &priv->netdev->stats; flags = cmd->rx_can.flags; - hwtstamp = kvaser_usb_hydra_ktime_from_rx_cmd(dev->cfg, cmd); + hwtstamp = kvaser_usb_hydra_ktime_from_cmd(dev->cfg, cmd); if (flags & KVASER_USB_HYDRA_CF_FLAG_ERROR_FRAME) { kvaser_usb_hydra_error_frame(priv, &cmd->rx_can.err_frame_data, @@ -1302,7 +1317,7 @@ static void kvaser_usb_hydra_rx_msg_ext(const struct kvaser_usb *dev, KVASER_USB_KCAN_DATA_DLC_SHIFT; flags = le32_to_cpu(cmd->rx_can.flags); - hwtstamp = kvaser_usb_hydra_ktime_from_rx_cmd(dev->cfg, std_cmd); + hwtstamp = kvaser_usb_hydra_ktime_from_cmd(dev->cfg, std_cmd); if (flags & KVASER_USB_HYDRA_CF_FLAG_ERROR_FRAME) { kvaser_usb_hydra_error_frame(priv, &cmd->rx_can.err_frame_data, diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 23bd7574b1c7..6b9122ab1464 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -119,6 +119,10 @@ /* Extended CAN identifier flag */ #define KVASER_EXTENDED_FRAME BIT(31) +/* USBCanII timestamp */ +#define KVASER_USB_USBCAN_CLK_OVERFLOW_MASK GENMASK(31, 16) +#define KVASER_USB_USBCAN_TIMESTAMP_FACTOR 10 + struct kvaser_cmd_simple { u8 tid; u8 channel; @@ -235,6 +239,20 @@ struct kvaser_cmd_tx_acknowledge_header { u8 tid; } __packed; +struct leaf_cmd_tx_acknowledge { + u8 channel; + u8 tid; + __le16 time[3]; + u8 padding[2]; +} __packed; + +struct usbcan_cmd_tx_acknowledge { + u8 channel; + u8 tid; + __le16 time; + u8 padding[2]; +} __packed; + struct leaf_cmd_can_error_event { u8 tid; u8 flags; @@ -281,6 +299,12 @@ struct usbcan_cmd_error_event { __le16 padding; } __packed; +struct usbcan_cmd_clk_overflow_event { + u8 tid; + u8 padding; + __le32 time; +} __packed; + struct kvaser_cmd_ctrl_mode { u8 tid; u8 channel; @@ -347,6 +371,7 @@ struct kvaser_cmd { struct leaf_cmd_error_event error_event; struct kvaser_cmd_cap_req cap_req; struct kvaser_cmd_cap_res cap_res; + struct leaf_cmd_tx_acknowledge tx_ack; } __packed leaf; union { @@ -355,6 +380,8 @@ struct kvaser_cmd { struct usbcan_cmd_chip_state_event chip_state_event; struct usbcan_cmd_can_error_event can_error_event; struct usbcan_cmd_error_event error_event; + struct usbcan_cmd_tx_acknowledge tx_ack; + struct usbcan_cmd_clk_overflow_event clk_overflow_event; } __packed usbcan; struct kvaser_cmd_tx_can tx_can; @@ -370,7 +397,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), - [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.leaf.tx_ack), [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo), [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can), [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), @@ -388,15 +415,14 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), - [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.usbcan.tx_ack), [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo), [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), - /* ignored events: */ - [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = kvaser_fsize(u.usbcan.clk_overflow_event), }; /* Summary of a kvaser error event, for a unified Leaf/Usbcan error @@ -463,11 +489,27 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = { .bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const, }; -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = { +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg_16mhz = { .clock = { .freq = 16 * MEGA /* Hz */, }, - .timestamp_freq = 1, + .timestamp_freq = 16, + .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg_24mhz = { + .clock = { + .freq = 16 * MEGA /* Hz */, + }, + .timestamp_freq = 24, + .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg_32mhz = { + .clock = { + .freq = 16 * MEGA /* Hz */, + }, + .timestamp_freq = 32, .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, }; @@ -475,7 +517,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = { .clock = { .freq = 16 * MEGA /* Hz */, }, - .timestamp_freq = 1, + .timestamp_freq = 16, .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; @@ -483,7 +525,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = { .clock = { .freq = 24 * MEGA /* Hz */, }, - .timestamp_freq = 1, + .timestamp_freq = 24, .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; @@ -491,10 +533,19 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = { .clock = { .freq = 32 * MEGA /* Hz */, }, - .timestamp_freq = 1, + .timestamp_freq = 32, .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; +static inline ktime_t kvaser_usb_usbcan_timestamp_to_ktime(const struct kvaser_usb *dev, + __le16 timestamp) +{ + u64 ticks = le16_to_cpu(timestamp) | + dev->card_data.usbcan_timestamp_msb; + + return kvaser_usb_ticks_to_ktime(dev->cfg, ticks * KVASER_USB_USBCAN_TIMESTAMP_FACTOR); +} + static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { @@ -678,8 +729,19 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { /* Firmware expects bittiming parameters calculated for 16MHz * clock, regardless of the actual clock + * Though, the reported freq is used for timestamps */ - dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg; + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg_16mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg_24mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg_32mhz; + break; + } } else { switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: @@ -880,6 +942,8 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, struct kvaser_usb_net_priv *priv; unsigned long flags; u8 channel, tid; + struct sk_buff *skb; + ktime_t hwtstamp = 0; channel = cmd->u.tx_acknowledge_header.channel; tid = cmd->u.tx_acknowledge_header.tid; @@ -901,14 +965,14 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, /* Sometimes the state change doesn't come after a bus-off event */ if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) { - struct sk_buff *skb; + struct sk_buff *err_skb; struct can_frame *cf; - skb = alloc_can_err_skb(priv->netdev, &cf); - if (skb) { + err_skb = alloc_can_err_skb(priv->netdev, &cf); + if (err_skb) { cf->can_id |= CAN_ERR_RESTARTED; - netif_rx(skb); + netif_rx(err_skb); } else { netdev_err(priv->netdev, "No memory left for err_skb\n"); @@ -919,9 +983,20 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, priv->can.state = CAN_STATE_ERROR_ACTIVE; } + switch (dev->driver_info->family) { + case KVASER_LEAF: + hwtstamp = kvaser_usb_timestamp48_to_ktime(dev->cfg, cmd->u.leaf.tx_ack.time); + break; + case KVASER_USBCAN: + hwtstamp = kvaser_usb_usbcan_timestamp_to_ktime(dev, cmd->u.usbcan.tx_ack.time); + break; + } spin_lock_irqsave(&priv->tx_contexts_lock, flags); + skb = priv->can.echo_skb[context->echo_index]; + if (skb) + skb_hwtstamps(skb)->hwtstamp = hwtstamp; stats->tx_packets++; stats->tx_bytes += can_get_echo_skb(priv->netdev, context->echo_index, NULL); @@ -1299,6 +1374,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, struct net_device_stats *stats; u8 channel = cmd->u.rx_can_header.channel; const u8 *rx_data = NULL; /* GCC */ + ktime_t hwtstamp = 0; if (channel >= dev->nchannels) { dev_err(&dev->intf->dev, @@ -1329,9 +1405,11 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, switch (dev->driver_info->family) { case KVASER_LEAF: rx_data = cmd->u.leaf.rx_can.data; + hwtstamp = kvaser_usb_timestamp48_to_ktime(dev->cfg, cmd->u.leaf.rx_can.time); break; case KVASER_USBCAN: rx_data = cmd->u.usbcan.rx_can.data; + hwtstamp = kvaser_usb_usbcan_timestamp_to_ktime(dev, cmd->u.usbcan.rx_can.time); break; } @@ -1375,6 +1453,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, memcpy(cf->data, &rx_data[6], cf->len); } + skb_hwtstamps(skb)->hwtstamp = hwtstamp; stats->rx_packets++; if (!(cf->can_id & CAN_RTR_FLAG)) stats->rx_bytes += cf->len; @@ -1508,7 +1587,7 @@ static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev, complete(&priv->get_busparams_comp); } -static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, +static void kvaser_usb_leaf_handle_command(struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) @@ -1554,12 +1633,15 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, kvaser_usb_leaf_get_busparams_reply(dev, cmd); break; - /* Ignored commands */ case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: if (dev->driver_info->family != KVASER_USBCAN) goto warn; + dev->card_data.usbcan_timestamp_msb = + le32_to_cpu(cmd->u.usbcan.clk_overflow_event.time) & + KVASER_USB_USBCAN_CLK_OVERFLOW_MASK; break; + /* Ignored commands */ case CMD_FLUSH_QUEUE_REPLY: if (dev->driver_info->family != KVASER_LEAF) goto warn; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index 3d68fef46ded..59f7cd8ceb39 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -901,11 +901,8 @@ int pcan_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info { info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; - info->phc_index = -1; info->tx_types = BIT(HWTSTAMP_TX_OFF); info->rx_filters = BIT(HWTSTAMP_FILTER_ALL); |