can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression
authorJimmy Assarsson <extja@kvaser.com>
Fri, 8 Jul 2022 18:48:45 +0000 (20:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Jul 2022 14:35:10 +0000 (16:35 +0200)
commit e6c80e601053ffdac5709f11ff3ec1e19ed05f7b upstream.

The firmware of M32C based Leaf devices expects bittiming parameters
calculated for 16MHz clock. Since we use the actual clock frequency of
the device, the device may end up with wrong bittiming parameters,
depending on user requested parameters.

This regression affects M32C based Leaf devices with non-16MHz clock.

Fixes: a8b513b824e4 ("can: kvaser_usb: get CAN clock frequency from device")
Link: https://lore.kernel.org/all/20220603083820.800246-3-extja@kvaser.com
Cc: stable@vger.kernel.org
Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/can/usb/kvaser_usb/kvaser_usb.h
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c

index 2e358e20d3d961cee2af761fd8a75864aedb8407..478e2eeec13603f195cbe5b1a9bc72a503b989f3 100644 (file)
@@ -38,6 +38,7 @@
 /* Kvaser USB device quirks */
 #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)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP                        0x01
index 45abf2093b666396a409c225ed9ec9b78be10913..e570f5a76bbfd0929514f96f4090c29ec92b2ff6 100644 (file)
@@ -101,26 +101,33 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = {
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = {
-       .quirks = 0,
+       .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
        .family = KVASER_LEAF,
        .ops = &kvaser_usb_leaf_dev_ops,
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = {
-       .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS,
+       .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
+                 KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
        .family = KVASER_LEAF,
        .ops = &kvaser_usb_leaf_dev_ops,
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = {
        .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
-                 KVASER_USB_QUIRK_HAS_SILENT_MODE,
+                 KVASER_USB_QUIRK_HAS_SILENT_MODE |
+                 KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
        .family = KVASER_LEAF,
        .ops = &kvaser_usb_leaf_dev_ops,
 };
 
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
+       .quirks = 0,
+       .ops = &kvaser_usb_leaf_dev_ops,
+};
+
 static const struct usb_device_id kvaser_usb_table[] = {
-       /* Leaf USB product IDs */
+       /* Leaf M32C USB product IDs */
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID),
                .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID),
@@ -161,22 +168,24 @@ static const struct usb_device_id kvaser_usb_table[] = {
                .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
                .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+
+       /* Leaf i.MX28 USB product IDs */
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
        { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID),
-               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+               .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 
        /* USBCANII USB product IDs */
        { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
index dda65bb66c1bd58ea7b9b7bccb6c88aade1e34f4..d94101c465080426d502c7de89bbde8301b3c035 100644 (file)
@@ -525,16 +525,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
        dev->fw_version = le32_to_cpu(softinfo->fw_version);
        dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
 
-       switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
-       case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+       if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+               /* Firmware expects bittiming parameters calculated for 16MHz
+                * clock, regardless of the actual clock
+                */
                dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
-               break;
-       case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
-               dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
-               break;
-       case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
-               dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
-               break;
+       } else {
+               switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
+               case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+                       dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
+                       break;
+               case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
+                       dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
+                       break;
+               case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
+                       dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
+                       break;
+               }
        }
 }