diff options
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/flexcan.c | 18 | ||||
-rw-r--r-- | drivers/net/can/usb/gs_usb.c | 2 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb.c | 69 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_ucan.h | 15 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 73 |
5 files changed, 113 insertions, 64 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 80c46ad4cee4..ad0a7e8c2c2b 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -592,13 +592,12 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) | |||
592 | rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? | 592 | rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? |
593 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; | 593 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; |
594 | new_state = max(tx_state, rx_state); | 594 | new_state = max(tx_state, rx_state); |
595 | } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) { | 595 | } else { |
596 | __flexcan_get_berr_counter(dev, &bec); | 596 | __flexcan_get_berr_counter(dev, &bec); |
597 | new_state = CAN_STATE_ERROR_PASSIVE; | 597 | new_state = flt == FLEXCAN_ESR_FLT_CONF_PASSIVE ? |
598 | CAN_STATE_ERROR_PASSIVE : CAN_STATE_BUS_OFF; | ||
598 | rx_state = bec.rxerr >= bec.txerr ? new_state : 0; | 599 | rx_state = bec.rxerr >= bec.txerr ? new_state : 0; |
599 | tx_state = bec.rxerr <= bec.txerr ? new_state : 0; | 600 | tx_state = bec.rxerr <= bec.txerr ? new_state : 0; |
600 | } else { | ||
601 | new_state = CAN_STATE_BUS_OFF; | ||
602 | } | 601 | } |
603 | 602 | ||
604 | /* state hasn't changed */ | 603 | /* state hasn't changed */ |
@@ -1158,12 +1157,19 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1158 | const struct flexcan_devtype_data *devtype_data; | 1157 | const struct flexcan_devtype_data *devtype_data; |
1159 | struct net_device *dev; | 1158 | struct net_device *dev; |
1160 | struct flexcan_priv *priv; | 1159 | struct flexcan_priv *priv; |
1160 | struct regulator *reg_xceiver; | ||
1161 | struct resource *mem; | 1161 | struct resource *mem; |
1162 | struct clk *clk_ipg = NULL, *clk_per = NULL; | 1162 | struct clk *clk_ipg = NULL, *clk_per = NULL; |
1163 | void __iomem *base; | 1163 | void __iomem *base; |
1164 | int err, irq; | 1164 | int err, irq; |
1165 | u32 clock_freq = 0; | 1165 | u32 clock_freq = 0; |
1166 | 1166 | ||
1167 | reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); | ||
1168 | if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER) | ||
1169 | return -EPROBE_DEFER; | ||
1170 | else if (IS_ERR(reg_xceiver)) | ||
1171 | reg_xceiver = NULL; | ||
1172 | |||
1167 | if (pdev->dev.of_node) | 1173 | if (pdev->dev.of_node) |
1168 | of_property_read_u32(pdev->dev.of_node, | 1174 | of_property_read_u32(pdev->dev.of_node, |
1169 | "clock-frequency", &clock_freq); | 1175 | "clock-frequency", &clock_freq); |
@@ -1224,9 +1230,7 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1224 | priv->pdata = dev_get_platdata(&pdev->dev); | 1230 | priv->pdata = dev_get_platdata(&pdev->dev); |
1225 | priv->devtype_data = devtype_data; | 1231 | priv->devtype_data = devtype_data; |
1226 | 1232 | ||
1227 | priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); | 1233 | priv->reg_xceiver = reg_xceiver; |
1228 | if (IS_ERR(priv->reg_xceiver)) | ||
1229 | priv->reg_xceiver = NULL; | ||
1230 | 1234 | ||
1231 | netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); | 1235 | netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); |
1232 | 1236 | ||
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 009acc8641fc..8b4d3e6875eb 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c | |||
@@ -901,6 +901,8 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
901 | } | 901 | } |
902 | 902 | ||
903 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 903 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
904 | if (!dev) | ||
905 | return -ENOMEM; | ||
904 | init_usb_anchor(&dev->rx_submitted); | 906 | init_usb_anchor(&dev->rx_submitted); |
905 | 907 | ||
906 | atomic_set(&dev->active_channels, 0); | 908 | atomic_set(&dev->active_channels, 0); |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index d269ae0b072a..4643914859b2 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/can/dev.h> | 25 | #include <linux/can/dev.h> |
26 | #include <linux/can/error.h> | 26 | #include <linux/can/error.h> |
27 | 27 | ||
28 | #define MAX_TX_URBS 16 | ||
29 | #define MAX_RX_URBS 4 | 28 | #define MAX_RX_URBS 4 |
30 | #define START_TIMEOUT 1000 /* msecs */ | 29 | #define START_TIMEOUT 1000 /* msecs */ |
31 | #define STOP_TIMEOUT 1000 /* msecs */ | 30 | #define STOP_TIMEOUT 1000 /* msecs */ |
@@ -443,6 +442,7 @@ struct kvaser_usb_error_summary { | |||
443 | }; | 442 | }; |
444 | }; | 443 | }; |
445 | 444 | ||
445 | /* Context for an outstanding, not yet ACKed, transmission */ | ||
446 | struct kvaser_usb_tx_urb_context { | 446 | struct kvaser_usb_tx_urb_context { |
447 | struct kvaser_usb_net_priv *priv; | 447 | struct kvaser_usb_net_priv *priv; |
448 | u32 echo_index; | 448 | u32 echo_index; |
@@ -456,8 +456,13 @@ struct kvaser_usb { | |||
456 | struct usb_endpoint_descriptor *bulk_in, *bulk_out; | 456 | struct usb_endpoint_descriptor *bulk_in, *bulk_out; |
457 | struct usb_anchor rx_submitted; | 457 | struct usb_anchor rx_submitted; |
458 | 458 | ||
459 | /* @max_tx_urbs: Firmware-reported maximum number of oustanding, | ||
460 | * not yet ACKed, transmissions on this device. This value is | ||
461 | * also used as a sentinel for marking free tx contexts. | ||
462 | */ | ||
459 | u32 fw_version; | 463 | u32 fw_version; |
460 | unsigned int nchannels; | 464 | unsigned int nchannels; |
465 | unsigned int max_tx_urbs; | ||
461 | enum kvaser_usb_family family; | 466 | enum kvaser_usb_family family; |
462 | 467 | ||
463 | bool rxinitdone; | 468 | bool rxinitdone; |
@@ -467,19 +472,18 @@ struct kvaser_usb { | |||
467 | 472 | ||
468 | struct kvaser_usb_net_priv { | 473 | struct kvaser_usb_net_priv { |
469 | struct can_priv can; | 474 | struct can_priv can; |
470 | 475 | struct can_berr_counter bec; | |
471 | spinlock_t tx_contexts_lock; | ||
472 | int active_tx_contexts; | ||
473 | struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS]; | ||
474 | |||
475 | struct usb_anchor tx_submitted; | ||
476 | struct completion start_comp, stop_comp; | ||
477 | 476 | ||
478 | struct kvaser_usb *dev; | 477 | struct kvaser_usb *dev; |
479 | struct net_device *netdev; | 478 | struct net_device *netdev; |
480 | int channel; | 479 | int channel; |
481 | 480 | ||
482 | struct can_berr_counter bec; | 481 | struct completion start_comp, stop_comp; |
482 | struct usb_anchor tx_submitted; | ||
483 | |||
484 | spinlock_t tx_contexts_lock; | ||
485 | int active_tx_contexts; | ||
486 | struct kvaser_usb_tx_urb_context tx_contexts[]; | ||
483 | }; | 487 | }; |
484 | 488 | ||
485 | static const struct usb_device_id kvaser_usb_table[] = { | 489 | static const struct usb_device_id kvaser_usb_table[] = { |
@@ -592,8 +596,8 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id, | |||
592 | * for further details. | 596 | * for further details. |
593 | */ | 597 | */ |
594 | if (tmp->len == 0) { | 598 | if (tmp->len == 0) { |
595 | pos = round_up(pos, | 599 | pos = round_up(pos, le16_to_cpu(dev->bulk_in-> |
596 | dev->bulk_in->wMaxPacketSize); | 600 | wMaxPacketSize)); |
597 | continue; | 601 | continue; |
598 | } | 602 | } |
599 | 603 | ||
@@ -657,9 +661,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev) | |||
657 | switch (dev->family) { | 661 | switch (dev->family) { |
658 | case KVASER_LEAF: | 662 | case KVASER_LEAF: |
659 | dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); | 663 | dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); |
664 | dev->max_tx_urbs = | ||
665 | le16_to_cpu(msg.u.leaf.softinfo.max_outstanding_tx); | ||
660 | break; | 666 | break; |
661 | case KVASER_USBCAN: | 667 | case KVASER_USBCAN: |
662 | dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); | 668 | dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); |
669 | dev->max_tx_urbs = | ||
670 | le16_to_cpu(msg.u.usbcan.softinfo.max_outstanding_tx); | ||
663 | break; | 671 | break; |
664 | } | 672 | } |
665 | 673 | ||
@@ -715,7 +723,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, | |||
715 | 723 | ||
716 | stats = &priv->netdev->stats; | 724 | stats = &priv->netdev->stats; |
717 | 725 | ||
718 | context = &priv->tx_contexts[tid % MAX_TX_URBS]; | 726 | context = &priv->tx_contexts[tid % dev->max_tx_urbs]; |
719 | 727 | ||
720 | /* Sometimes the state change doesn't come after a bus-off event */ | 728 | /* Sometimes the state change doesn't come after a bus-off event */ |
721 | if (priv->can.restart_ms && | 729 | if (priv->can.restart_ms && |
@@ -744,7 +752,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, | |||
744 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); | 752 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); |
745 | 753 | ||
746 | can_get_echo_skb(priv->netdev, context->echo_index); | 754 | can_get_echo_skb(priv->netdev, context->echo_index); |
747 | context->echo_index = MAX_TX_URBS; | 755 | context->echo_index = dev->max_tx_urbs; |
748 | --priv->active_tx_contexts; | 756 | --priv->active_tx_contexts; |
749 | netif_wake_queue(priv->netdev); | 757 | netif_wake_queue(priv->netdev); |
750 | 758 | ||
@@ -1329,7 +1337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) | |||
1329 | * number of events in case of a heavy rx load on the bus. | 1337 | * number of events in case of a heavy rx load on the bus. |
1330 | */ | 1338 | */ |
1331 | if (msg->len == 0) { | 1339 | if (msg->len == 0) { |
1332 | pos = round_up(pos, dev->bulk_in->wMaxPacketSize); | 1340 | pos = round_up(pos, le16_to_cpu(dev->bulk_in-> |
1341 | wMaxPacketSize)); | ||
1333 | continue; | 1342 | continue; |
1334 | } | 1343 | } |
1335 | 1344 | ||
@@ -1512,11 +1521,13 @@ error: | |||
1512 | 1521 | ||
1513 | static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) | 1522 | static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) |
1514 | { | 1523 | { |
1515 | int i; | 1524 | int i, max_tx_urbs; |
1525 | |||
1526 | max_tx_urbs = priv->dev->max_tx_urbs; | ||
1516 | 1527 | ||
1517 | priv->active_tx_contexts = 0; | 1528 | priv->active_tx_contexts = 0; |
1518 | for (i = 0; i < MAX_TX_URBS; i++) | 1529 | for (i = 0; i < max_tx_urbs; i++) |
1519 | priv->tx_contexts[i].echo_index = MAX_TX_URBS; | 1530 | priv->tx_contexts[i].echo_index = max_tx_urbs; |
1520 | } | 1531 | } |
1521 | 1532 | ||
1522 | /* This method might sleep. Do not call it in the atomic context | 1533 | /* This method might sleep. Do not call it in the atomic context |
@@ -1702,14 +1713,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1702 | *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; | 1713 | *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; |
1703 | 1714 | ||
1704 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); | 1715 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); |
1705 | for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { | 1716 | for (i = 0; i < dev->max_tx_urbs; i++) { |
1706 | if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { | 1717 | if (priv->tx_contexts[i].echo_index == dev->max_tx_urbs) { |
1707 | context = &priv->tx_contexts[i]; | 1718 | context = &priv->tx_contexts[i]; |
1708 | 1719 | ||
1709 | context->echo_index = i; | 1720 | context->echo_index = i; |
1710 | can_put_echo_skb(skb, netdev, context->echo_index); | 1721 | can_put_echo_skb(skb, netdev, context->echo_index); |
1711 | ++priv->active_tx_contexts; | 1722 | ++priv->active_tx_contexts; |
1712 | if (priv->active_tx_contexts >= MAX_TX_URBS) | 1723 | if (priv->active_tx_contexts >= dev->max_tx_urbs) |
1713 | netif_stop_queue(netdev); | 1724 | netif_stop_queue(netdev); |
1714 | 1725 | ||
1715 | break; | 1726 | break; |
@@ -1743,7 +1754,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1743 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); | 1754 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); |
1744 | 1755 | ||
1745 | can_free_echo_skb(netdev, context->echo_index); | 1756 | can_free_echo_skb(netdev, context->echo_index); |
1746 | context->echo_index = MAX_TX_URBS; | 1757 | context->echo_index = dev->max_tx_urbs; |
1747 | --priv->active_tx_contexts; | 1758 | --priv->active_tx_contexts; |
1748 | netif_wake_queue(netdev); | 1759 | netif_wake_queue(netdev); |
1749 | 1760 | ||
@@ -1881,7 +1892,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf, | |||
1881 | if (err) | 1892 | if (err) |
1882 | return err; | 1893 | return err; |
1883 | 1894 | ||
1884 | netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); | 1895 | netdev = alloc_candev(sizeof(*priv) + |
1896 | dev->max_tx_urbs * sizeof(*priv->tx_contexts), | ||
1897 | dev->max_tx_urbs); | ||
1885 | if (!netdev) { | 1898 | if (!netdev) { |
1886 | dev_err(&intf->dev, "Cannot alloc candev\n"); | 1899 | dev_err(&intf->dev, "Cannot alloc candev\n"); |
1887 | return -ENOMEM; | 1900 | return -ENOMEM; |
@@ -2009,6 +2022,13 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
2009 | return err; | 2022 | return err; |
2010 | } | 2023 | } |
2011 | 2024 | ||
2025 | dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n", | ||
2026 | ((dev->fw_version >> 24) & 0xff), | ||
2027 | ((dev->fw_version >> 16) & 0xff), | ||
2028 | (dev->fw_version & 0xffff)); | ||
2029 | |||
2030 | dev_dbg(&intf->dev, "Max oustanding tx = %d URBs\n", dev->max_tx_urbs); | ||
2031 | |||
2012 | err = kvaser_usb_get_card_info(dev); | 2032 | err = kvaser_usb_get_card_info(dev); |
2013 | if (err) { | 2033 | if (err) { |
2014 | dev_err(&intf->dev, | 2034 | dev_err(&intf->dev, |
@@ -2016,11 +2036,6 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
2016 | return err; | 2036 | return err; |
2017 | } | 2037 | } |
2018 | 2038 | ||
2019 | dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n", | ||
2020 | ((dev->fw_version >> 24) & 0xff), | ||
2021 | ((dev->fw_version >> 16) & 0xff), | ||
2022 | (dev->fw_version & 0xffff)); | ||
2023 | |||
2024 | for (i = 0; i < dev->nchannels; i++) { | 2039 | for (i = 0; i < dev->nchannels; i++) { |
2025 | err = kvaser_usb_init_one(intf, id, i); | 2040 | err = kvaser_usb_init_one(intf, id, i); |
2026 | if (err) { | 2041 | if (err) { |
diff --git a/drivers/net/can/usb/peak_usb/pcan_ucan.h b/drivers/net/can/usb/peak_usb/pcan_ucan.h index 1ba7c25002e1..e8fc4952c6b0 100644 --- a/drivers/net/can/usb/peak_usb/pcan_ucan.h +++ b/drivers/net/can/usb/peak_usb/pcan_ucan.h | |||
@@ -26,8 +26,8 @@ | |||
26 | #define PUCAN_CMD_FILTER_STD 0x008 | 26 | #define PUCAN_CMD_FILTER_STD 0x008 |
27 | #define PUCAN_CMD_TX_ABORT 0x009 | 27 | #define PUCAN_CMD_TX_ABORT 0x009 |
28 | #define PUCAN_CMD_WR_ERR_CNT 0x00a | 28 | #define PUCAN_CMD_WR_ERR_CNT 0x00a |
29 | #define PUCAN_CMD_RX_FRAME_ENABLE 0x00b | 29 | #define PUCAN_CMD_SET_EN_OPTION 0x00b |
30 | #define PUCAN_CMD_RX_FRAME_DISABLE 0x00c | 30 | #define PUCAN_CMD_CLR_DIS_OPTION 0x00c |
31 | #define PUCAN_CMD_END_OF_COLLECTION 0x3ff | 31 | #define PUCAN_CMD_END_OF_COLLECTION 0x3ff |
32 | 32 | ||
33 | /* uCAN received messages list */ | 33 | /* uCAN received messages list */ |
@@ -101,14 +101,15 @@ struct __packed pucan_wr_err_cnt { | |||
101 | u16 unused; | 101 | u16 unused; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | /* uCAN RX_FRAME_ENABLE command fields */ | 104 | /* uCAN SET_EN/CLR_DIS _OPTION command fields */ |
105 | #define PUCAN_FLTEXT_ERROR 0x0001 | 105 | #define PUCAN_OPTION_ERROR 0x0001 |
106 | #define PUCAN_FLTEXT_BUSLOAD 0x0002 | 106 | #define PUCAN_OPTION_BUSLOAD 0x0002 |
107 | #define PUCAN_OPTION_CANDFDISO 0x0004 | ||
107 | 108 | ||
108 | struct __packed pucan_filter_ext { | 109 | struct __packed pucan_options { |
109 | __le16 opcode_channel; | 110 | __le16 opcode_channel; |
110 | 111 | ||
111 | __le16 ext_mask; | 112 | __le16 options; |
112 | u32 unused; | 113 | u32 unused; |
113 | }; | 114 | }; |
114 | 115 | ||
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index 00481eeb9924..09d14e70abd7 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c | |||
@@ -110,13 +110,13 @@ struct __packed pcan_ufd_led { | |||
110 | u8 unused[5]; | 110 | u8 unused[5]; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | /* Extended usage of uCAN commands CMD_RX_FRAME_xxxABLE for PCAN-USB Pro FD */ | 113 | /* Extended usage of uCAN commands CMD_xxx_xx_OPTION for PCAN-USB Pro FD */ |
114 | #define PCAN_UFD_FLTEXT_CALIBRATION 0x8000 | 114 | #define PCAN_UFD_FLTEXT_CALIBRATION 0x8000 |
115 | 115 | ||
116 | struct __packed pcan_ufd_filter_ext { | 116 | struct __packed pcan_ufd_options { |
117 | __le16 opcode_channel; | 117 | __le16 opcode_channel; |
118 | 118 | ||
119 | __le16 ext_mask; | 119 | __le16 ucan_mask; |
120 | u16 unused; | 120 | u16 unused; |
121 | __le16 usb_mask; | 121 | __le16 usb_mask; |
122 | }; | 122 | }; |
@@ -251,6 +251,27 @@ static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf) | |||
251 | /* moves the pointer forward */ | 251 | /* moves the pointer forward */ |
252 | pc += sizeof(struct pucan_wr_err_cnt); | 252 | pc += sizeof(struct pucan_wr_err_cnt); |
253 | 253 | ||
254 | /* add command to switch from ISO to non-ISO mode, if fw allows it */ | ||
255 | if (dev->can.ctrlmode_supported & CAN_CTRLMODE_FD_NON_ISO) { | ||
256 | struct pucan_options *puo = (struct pucan_options *)pc; | ||
257 | |||
258 | puo->opcode_channel = | ||
259 | (dev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) ? | ||
260 | pucan_cmd_opcode_channel(dev, | ||
261 | PUCAN_CMD_CLR_DIS_OPTION) : | ||
262 | pucan_cmd_opcode_channel(dev, PUCAN_CMD_SET_EN_OPTION); | ||
263 | |||
264 | puo->options = cpu_to_le16(PUCAN_OPTION_CANDFDISO); | ||
265 | |||
266 | /* to be sure that no other extended bits will be taken into | ||
267 | * account | ||
268 | */ | ||
269 | puo->unused = 0; | ||
270 | |||
271 | /* moves the pointer forward */ | ||
272 | pc += sizeof(struct pucan_options); | ||
273 | } | ||
274 | |||
254 | /* next, go back to operational mode */ | 275 | /* next, go back to operational mode */ |
255 | cmd = (struct pucan_command *)pc; | 276 | cmd = (struct pucan_command *)pc; |
256 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | 277 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, |
@@ -321,21 +342,21 @@ static int pcan_usb_fd_set_filter_std(struct peak_usb_device *dev, int idx, | |||
321 | return pcan_usb_fd_send_cmd(dev, cmd); | 342 | return pcan_usb_fd_send_cmd(dev, cmd); |
322 | } | 343 | } |
323 | 344 | ||
324 | /* set/unset notifications filter: | 345 | /* set/unset options |
325 | * | 346 | * |
326 | * onoff sets(1)/unset(0) notifications | 347 | * onoff set(1)/unset(0) options |
327 | * mask each bit defines a kind of notification to set/unset | 348 | * mask each bit defines a kind of options to set/unset |
328 | */ | 349 | */ |
329 | static int pcan_usb_fd_set_filter_ext(struct peak_usb_device *dev, | 350 | static int pcan_usb_fd_set_options(struct peak_usb_device *dev, |
330 | bool onoff, u16 ext_mask, u16 usb_mask) | 351 | bool onoff, u16 ucan_mask, u16 usb_mask) |
331 | { | 352 | { |
332 | struct pcan_ufd_filter_ext *cmd = pcan_usb_fd_cmd_buffer(dev); | 353 | struct pcan_ufd_options *cmd = pcan_usb_fd_cmd_buffer(dev); |
333 | 354 | ||
334 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | 355 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, |
335 | (onoff) ? PUCAN_CMD_RX_FRAME_ENABLE : | 356 | (onoff) ? PUCAN_CMD_SET_EN_OPTION : |
336 | PUCAN_CMD_RX_FRAME_DISABLE); | 357 | PUCAN_CMD_CLR_DIS_OPTION); |
337 | 358 | ||
338 | cmd->ext_mask = cpu_to_le16(ext_mask); | 359 | cmd->ucan_mask = cpu_to_le16(ucan_mask); |
339 | cmd->usb_mask = cpu_to_le16(usb_mask); | 360 | cmd->usb_mask = cpu_to_le16(usb_mask); |
340 | 361 | ||
341 | /* send the command */ | 362 | /* send the command */ |
@@ -770,9 +791,9 @@ static int pcan_usb_fd_start(struct peak_usb_device *dev) | |||
770 | &pcan_usb_pro_fd); | 791 | &pcan_usb_pro_fd); |
771 | 792 | ||
772 | /* enable USB calibration messages */ | 793 | /* enable USB calibration messages */ |
773 | err = pcan_usb_fd_set_filter_ext(dev, 1, | 794 | err = pcan_usb_fd_set_options(dev, 1, |
774 | PUCAN_FLTEXT_ERROR, | 795 | PUCAN_OPTION_ERROR, |
775 | PCAN_UFD_FLTEXT_CALIBRATION); | 796 | PCAN_UFD_FLTEXT_CALIBRATION); |
776 | } | 797 | } |
777 | 798 | ||
778 | pdev->usb_if->dev_opened_count++; | 799 | pdev->usb_if->dev_opened_count++; |
@@ -806,9 +827,9 @@ static int pcan_usb_fd_stop(struct peak_usb_device *dev) | |||
806 | 827 | ||
807 | /* turn off special msgs for that interface if no other dev opened */ | 828 | /* turn off special msgs for that interface if no other dev opened */ |
808 | if (pdev->usb_if->dev_opened_count == 1) | 829 | if (pdev->usb_if->dev_opened_count == 1) |
809 | pcan_usb_fd_set_filter_ext(dev, 0, | 830 | pcan_usb_fd_set_options(dev, 0, |
810 | PUCAN_FLTEXT_ERROR, | 831 | PUCAN_OPTION_ERROR, |
811 | PCAN_UFD_FLTEXT_CALIBRATION); | 832 | PCAN_UFD_FLTEXT_CALIBRATION); |
812 | pdev->usb_if->dev_opened_count--; | 833 | pdev->usb_if->dev_opened_count--; |
813 | 834 | ||
814 | return 0; | 835 | return 0; |
@@ -860,8 +881,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) | |||
860 | pdev->usb_if->fw_info.fw_version[2], | 881 | pdev->usb_if->fw_info.fw_version[2], |
861 | dev->adapter->ctrl_count); | 882 | dev->adapter->ctrl_count); |
862 | 883 | ||
863 | /* the currently supported hw is non-ISO */ | 884 | /* check for ability to switch between ISO/non-ISO modes */ |
864 | dev->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO; | 885 | if (pdev->usb_if->fw_info.fw_version[0] >= 2) { |
886 | /* firmware >= 2.x supports ISO/non-ISO switching */ | ||
887 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO; | ||
888 | } else { | ||
889 | /* firmware < 2.x only supports fixed(!) non-ISO */ | ||
890 | dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO; | ||
891 | } | ||
865 | 892 | ||
866 | /* tell the hardware the can driver is running */ | 893 | /* tell the hardware the can driver is running */ |
867 | err = pcan_usb_fd_drv_loaded(dev, 1); | 894 | err = pcan_usb_fd_drv_loaded(dev, 1); |
@@ -937,9 +964,9 @@ static void pcan_usb_fd_exit(struct peak_usb_device *dev) | |||
937 | if (dev->ctrl_idx == 0) { | 964 | if (dev->ctrl_idx == 0) { |
938 | /* turn off calibration message if any device were opened */ | 965 | /* turn off calibration message if any device were opened */ |
939 | if (pdev->usb_if->dev_opened_count > 0) | 966 | if (pdev->usb_if->dev_opened_count > 0) |
940 | pcan_usb_fd_set_filter_ext(dev, 0, | 967 | pcan_usb_fd_set_options(dev, 0, |
941 | PUCAN_FLTEXT_ERROR, | 968 | PUCAN_OPTION_ERROR, |
942 | PCAN_UFD_FLTEXT_CALIBRATION); | 969 | PCAN_UFD_FLTEXT_CALIBRATION); |
943 | 970 | ||
944 | /* tell USB adapter that the driver is being unloaded */ | 971 | /* tell USB adapter that the driver is being unloaded */ |
945 | pcan_usb_fd_drv_loaded(dev, 0); | 972 | pcan_usb_fd_drv_loaded(dev, 0); |