Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'linux-can-next-for-6.17-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2025-07-25

The first patch is by Khaled Elnaggar and converts the janz-ican3
driver's fwinfo_show() to sysfs_emit().

Vincent Mailhol contributes 3 patches that first fix a warning in the
ti_hecc driver and then add missing COMPILE_TEST more compile
coverage to the ti_hecc and tscan1 driver.

Randy Dunlap's patch let's the tscan1 driver depend on PC104.

A patch by Luis Felipe Hernandez fixes a kernel-doc error in the
ctucanfd driver.

Jimmy Assarsson contributes 10 patches for the kvaser_pciefd and 11
for the kvaser_usb driver. Both series simplify the identification of
physical the CAN interfaces and add devlink support to get information
about the running firmware.

* tag 'linux-can-next-for-6.17-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: (27 commits)
Documentation: devlink: add devlink documentation for the kvaser_usb driver
can: kvaser_usb: Add devlink port support
can: kvaser_usb: Expose device information via devlink info_get()
can: kvaser_usb: Add devlink support
can: kvaser_usb: Store additional device information
can: kvaser_usb: Store the different firmware version components in a struct
can: kvaser_usb: Move comment regarding max_tx_urbs
can: kvaser_usb: Add intermediate variables
can: kvaser_usb: Assign netdev.dev_port based on device channel index
can: kvaser_usb: Add support for ethtool set_phys_id()
can: kvaser_usb: Add support to control CAN LEDs on device
Documentation: devlink: add devlink documentation for the kvaser_pciefd driver
can: kvaser_pciefd: Add devlink port support
can: kvaser_pciefd: Expose device firmware version via devlink info_get()
can: kvaser_pciefd: Add devlink support
can: kvaser_pciefd: Split driver into C-file and header-file.
can: kvaser_pciefd: Store device channel index
can: kvaser_pciefd: Store the different firmware version components in a struct
can: kvaser_pciefd: Add intermediate variable for device struct in probe()
can: kvaser_pciefd: Add support for ethtool set_phys_id()
...
====================

Link: https://patch.msgid.link/20250725161327.4165174-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+655 -131
+2
Documentation/networking/devlink/index.rst
··· 85 85 ionic 86 86 ice 87 87 ixgbe 88 + kvaser_pciefd 89 + kvaser_usb 88 90 mlx4 89 91 mlx5 90 92 mlxsw
+24
Documentation/networking/devlink/kvaser_pciefd.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ============================= 4 + kvaser_pciefd devlink support 5 + ============================= 6 + 7 + This document describes the devlink features implemented by the 8 + ``kvaser_pciefd`` device driver. 9 + 10 + Info versions 11 + ============= 12 + 13 + The ``kvaser_pciefd`` driver reports the following versions 14 + 15 + .. list-table:: devlink info versions implemented 16 + :widths: 5 5 90 17 + 18 + * - Name 19 + - Type 20 + - Description 21 + * - ``fw`` 22 + - running 23 + - Version of the firmware running on the device. Also available 24 + through ``ethtool -i`` as ``firmware-version``.
+33
Documentation/networking/devlink/kvaser_usb.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ========================== 4 + kvaser_usb devlink support 5 + ========================== 6 + 7 + This document describes the devlink features implemented by the 8 + ``kvaser_usb`` device driver. 9 + 10 + Info versions 11 + ============= 12 + 13 + The ``kvaser_usb`` driver reports the following versions 14 + 15 + .. list-table:: devlink info versions implemented 16 + :widths: 5 5 90 17 + 18 + * - Name 19 + - Type 20 + - Description 21 + * - ``fw`` 22 + - running 23 + - Version of the firmware running on the device. Also available 24 + through ``ethtool -i`` as ``firmware-version``. 25 + * - ``board.rev`` 26 + - fixed 27 + - The device hardware revision. 28 + * - ``board.id`` 29 + - fixed 30 + - The device EAN (product number). 31 + * - ``serial_number`` 32 + - fixed 33 + - The device serial number.
+2 -1
drivers/net/can/Kconfig
··· 154 154 config CAN_KVASER_PCIEFD 155 155 depends on PCI 156 156 tristate "Kvaser PCIe FD cards" 157 + select NET_DEVLINK 157 158 help 158 159 This is a driver for the Kvaser PCI Express CAN FD family. 159 160 ··· 202 201 be called sun4i_can. 203 202 204 203 config CAN_TI_HECC 205 - depends on ARM 204 + depends on ARM || COMPILE_TEST 206 205 tristate "TI High End CAN Controller" 207 206 select CAN_RX_OFFLOAD 208 207 help
+1 -1
drivers/net/can/Makefile
··· 25 25 obj-$(CONFIG_CAN_GRCAN) += grcan.o 26 26 obj-$(CONFIG_CAN_IFI_CANFD) += ifi_canfd/ 27 27 obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o 28 - obj-$(CONFIG_CAN_KVASER_PCIEFD) += kvaser_pciefd.o 28 + obj-$(CONFIG_CAN_KVASER_PCIEFD) += kvaser_pciefd/ 29 29 obj-$(CONFIG_CAN_MSCAN) += mscan/ 30 30 obj-$(CONFIG_CAN_M_CAN) += m_can/ 31 31 obj-$(CONFIG_CAN_PEAK_PCIEFD) += peak_canfd/
+6 -5
drivers/net/can/ctucanfd/ctucanfd_base.c
··· 506 506 * @buf: TXT Buffer index to which frame is inserted (0-based) 507 507 * @isfdf: True - CAN FD Frame, False - CAN 2.0 Frame 508 508 * 509 - * Return: True - Frame inserted successfully 510 - * False - Frame was not inserted due to one of: 511 - * 1. TXT Buffer is not writable (it is in wrong state) 512 - * 2. Invalid TXT buffer index 513 - * 3. Invalid frame length 509 + * Return: 510 + * * True - Frame inserted successfully 511 + * * False - Frame was not inserted due to one of: 512 + * 1. TXT Buffer is not writable (it is in wrong state) 513 + * 2. Invalid TXT buffer index 514 + * 3. Invalid frame length 514 515 */ 515 516 static bool ctucan_insert_frame(struct ctucan_priv *priv, const struct canfd_frame *cf, u8 buf, 516 517 bool isfdf)
+1 -1
drivers/net/can/janz-ican3.c
··· 1867 1867 { 1868 1868 struct ican3_dev *mod = netdev_priv(to_net_dev(dev)); 1869 1869 1870 - return scnprintf(buf, PAGE_SIZE, "%s\n", mod->fwinfo); 1870 + return sysfs_emit(buf, "%s\n", mod->fwinfo); 1871 1871 } 1872 1872 1873 1873 static DEVICE_ATTR_RW(termination);
+71 -73
drivers/net/can/kvaser_pciefd.c drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c
··· 5 5 * - PEAK linux canfd driver 6 6 */ 7 7 8 + #include "kvaser_pciefd.h" 9 + 8 10 #include <linux/bitfield.h> 9 11 #include <linux/can/dev.h> 10 12 #include <linux/device.h> ··· 29 27 #define KVASER_PCIEFD_WAIT_TIMEOUT msecs_to_jiffies(1000) 30 28 #define KVASER_PCIEFD_BEC_POLL_FREQ (jiffies + msecs_to_jiffies(200)) 31 29 #define KVASER_PCIEFD_MAX_ERR_REP 256U 32 - #define KVASER_PCIEFD_CAN_TX_MAX_COUNT 17U 33 - #define KVASER_PCIEFD_MAX_CAN_CHANNELS 8UL 34 - #define KVASER_PCIEFD_DMA_COUNT 2U 35 - #define KVASER_PCIEFD_DMA_SIZE (4U * 1024U) 36 30 37 31 #define KVASER_PCIEFD_VENDOR 0x1a07 38 32 ··· 64 66 #define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180 65 67 #define KVASER_PCIEFD_KCAN_CTRL_REG 0x2c0 66 68 #define KVASER_PCIEFD_KCAN_CMD_REG 0x400 69 + #define KVASER_PCIEFD_KCAN_IOC_REG 0x404 67 70 #define KVASER_PCIEFD_KCAN_IEN_REG 0x408 68 71 #define KVASER_PCIEFD_KCAN_IRQ_REG 0x410 69 72 #define KVASER_PCIEFD_KCAN_TX_NR_PACKETS_REG 0x414 ··· 134 135 #define KVASER_PCIEFD_KCAN_CMD_AT BIT(1) 135 136 /* Request status packet */ 136 137 #define KVASER_PCIEFD_KCAN_CMD_SRQ BIT(0) 138 + 139 + /* Control CAN LED, active low */ 140 + #define KVASER_PCIEFD_KCAN_IOC_LED BIT(0) 137 141 138 142 /* Transmitter unaligned */ 139 143 #define KVASER_PCIEFD_KCAN_IRQ_TAL BIT(17) ··· 294 292 static void kvaser_pciefd_write_dma_map_xilinx(struct kvaser_pciefd *pcie, 295 293 dma_addr_t addr, int index); 296 294 297 - struct kvaser_pciefd_address_offset { 298 - u32 serdes; 299 - u32 pci_ien; 300 - u32 pci_irq; 301 - u32 sysid; 302 - u32 loopback; 303 - u32 kcan_srb_fifo; 304 - u32 kcan_srb; 305 - u32 kcan_ch0; 306 - u32 kcan_ch1; 307 - }; 308 - 309 - struct kvaser_pciefd_dev_ops { 310 - void (*kvaser_pciefd_write_dma_map)(struct kvaser_pciefd *pcie, 311 - dma_addr_t addr, int index); 312 - }; 313 - 314 - struct kvaser_pciefd_irq_mask { 315 - u32 kcan_rx0; 316 - u32 kcan_tx[KVASER_PCIEFD_MAX_CAN_CHANNELS]; 317 - u32 all; 318 - }; 319 - 320 - struct kvaser_pciefd_driver_data { 321 - const struct kvaser_pciefd_address_offset *address_offset; 322 - const struct kvaser_pciefd_irq_mask *irq_mask; 323 - const struct kvaser_pciefd_dev_ops *ops; 324 - }; 325 - 326 295 static const struct kvaser_pciefd_address_offset kvaser_pciefd_altera_address_offset = { 327 296 .serdes = 0x1000, 328 297 .pci_ien = 0x50, ··· 376 403 .address_offset = &kvaser_pciefd_xilinx_address_offset, 377 404 .irq_mask = &kvaser_pciefd_xilinx_irq_mask, 378 405 .ops = &kvaser_pciefd_xilinx_dev_ops, 379 - }; 380 - 381 - struct kvaser_pciefd_can { 382 - struct can_priv can; 383 - struct kvaser_pciefd *kv_pcie; 384 - void __iomem *reg_base; 385 - struct can_berr_counter bec; 386 - u8 cmd_seq; 387 - u8 tx_max_count; 388 - u8 tx_idx; 389 - u8 ack_idx; 390 - int err_rep_cnt; 391 - unsigned int completed_tx_pkts; 392 - unsigned int completed_tx_bytes; 393 - spinlock_t lock; /* Locks sensitive registers (e.g. MODE) */ 394 - struct timer_list bec_poll_timer; 395 - struct completion start_comp, flush_comp; 396 - }; 397 - 398 - struct kvaser_pciefd { 399 - struct pci_dev *pci; 400 - void __iomem *reg_base; 401 - struct kvaser_pciefd_can *can[KVASER_PCIEFD_MAX_CAN_CHANNELS]; 402 - const struct kvaser_pciefd_driver_data *driver_data; 403 - void *dma_data[KVASER_PCIEFD_DMA_COUNT]; 404 - u8 nr_channels; 405 - u32 bus_freq; 406 - u32 freq; 407 - u32 freq_to_ticks_div; 408 406 }; 409 407 410 408 struct kvaser_pciefd_rx_packet { ··· 470 526 static inline void kvaser_pciefd_abort_flush_reset(struct kvaser_pciefd_can *can) 471 527 { 472 528 kvaser_pciefd_send_kcan_cmd(can, KVASER_PCIEFD_KCAN_CMD_AT); 529 + } 530 + 531 + static inline void kvaser_pciefd_set_led(struct kvaser_pciefd_can *can, bool on) 532 + { 533 + if (on) 534 + can->ioc &= ~KVASER_PCIEFD_KCAN_IOC_LED; 535 + else 536 + can->ioc |= KVASER_PCIEFD_KCAN_IOC_LED; 537 + 538 + iowrite32(can->ioc, can->reg_base + KVASER_PCIEFD_KCAN_IOC_REG); 473 539 } 474 540 475 541 static void kvaser_pciefd_enable_err_gen(struct kvaser_pciefd_can *can) ··· 907 953 .ndo_change_mtu = can_change_mtu, 908 954 }; 909 955 956 + static int kvaser_pciefd_set_phys_id(struct net_device *netdev, 957 + enum ethtool_phys_id_state state) 958 + { 959 + struct kvaser_pciefd_can *can = netdev_priv(netdev); 960 + 961 + switch (state) { 962 + case ETHTOOL_ID_ACTIVE: 963 + return 3; /* 3 On/Off cycles per second */ 964 + 965 + case ETHTOOL_ID_ON: 966 + kvaser_pciefd_set_led(can, true); 967 + return 0; 968 + 969 + case ETHTOOL_ID_OFF: 970 + case ETHTOOL_ID_INACTIVE: 971 + kvaser_pciefd_set_led(can, false); 972 + return 0; 973 + 974 + default: 975 + return -EINVAL; 976 + } 977 + } 978 + 910 979 static const struct ethtool_ops kvaser_pciefd_ethtool_ops = { 911 980 .get_ts_info = can_ethtool_op_get_ts_info_hwts, 981 + .set_phys_id = kvaser_pciefd_set_phys_id, 912 982 }; 913 983 914 984 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) ··· 943 965 struct net_device *netdev; 944 966 struct kvaser_pciefd_can *can; 945 967 u32 status, tx_nr_packets_max; 968 + int ret; 946 969 947 970 netdev = alloc_candev(sizeof(struct kvaser_pciefd_can), 948 971 roundup_pow_of_two(KVASER_PCIEFD_CAN_TX_MAX_COUNT)); ··· 961 982 can->completed_tx_bytes = 0; 962 983 can->bec.txerr = 0; 963 984 can->bec.rxerr = 0; 985 + can->can.dev->dev_port = i; 964 986 965 987 init_completion(&can->start_comp); 966 988 init_completion(&can->flush_comp); ··· 969 989 970 990 /* Disable Bus load reporting */ 971 991 iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); 992 + 993 + can->ioc = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_IOC_REG); 994 + kvaser_pciefd_set_led(can, false); 972 995 973 996 tx_nr_packets_max = 974 997 FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_MAX_MASK, ··· 1014 1031 1015 1032 pcie->can[i] = can; 1016 1033 kvaser_pciefd_pwm_start(can); 1034 + ret = kvaser_pciefd_devlink_port_register(can); 1035 + if (ret) { 1036 + dev_err(&pcie->pci->dev, "Failed to register devlink port\n"); 1037 + return ret; 1038 + } 1017 1039 } 1018 1040 1019 1041 return 0; ··· 1151 1163 u32 version, srb_status, build; 1152 1164 1153 1165 version = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_VERSION_REG); 1166 + build = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_BUILD_REG); 1154 1167 pcie->nr_channels = min(KVASER_PCIEFD_MAX_CAN_CHANNELS, 1155 1168 FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_NR_CHAN_MASK, version)); 1156 - 1157 - build = ioread32(KVASER_PCIEFD_SYSID_ADDR(pcie) + KVASER_PCIEFD_SYSID_BUILD_REG); 1158 - dev_dbg(&pcie->pci->dev, "Version %lu.%lu.%lu\n", 1159 - FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MAJOR_MASK, version), 1160 - FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MINOR_MASK, version), 1161 - FIELD_GET(KVASER_PCIEFD_SYSID_BUILD_SEQ_MASK, build)); 1169 + pcie->fw_version.major = FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MAJOR_MASK, version); 1170 + pcie->fw_version.minor = FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MINOR_MASK, version); 1171 + pcie->fw_version.build = FIELD_GET(KVASER_PCIEFD_SYSID_BUILD_SEQ_MASK, build); 1162 1172 1163 1173 srb_status = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_STAT_REG); 1164 1174 if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DMA)) { ··· 1738 1752 if (can) { 1739 1753 iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 1740 1754 kvaser_pciefd_pwm_stop(can); 1755 + kvaser_pciefd_devlink_port_unregister(can); 1741 1756 free_candev(can->can.dev); 1742 1757 } 1743 1758 } ··· 1758 1771 const struct pci_device_id *id) 1759 1772 { 1760 1773 int ret; 1774 + struct devlink *devlink; 1775 + struct device *dev = &pdev->dev; 1761 1776 struct kvaser_pciefd *pcie; 1762 1777 const struct kvaser_pciefd_irq_mask *irq_mask; 1763 1778 1764 - pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); 1765 - if (!pcie) 1779 + devlink = devlink_alloc(&kvaser_pciefd_devlink_ops, sizeof(*pcie), dev); 1780 + if (!devlink) 1766 1781 return -ENOMEM; 1767 1782 1783 + pcie = devlink_priv(devlink); 1768 1784 pci_set_drvdata(pdev, pcie); 1769 1785 pcie->pci = pdev; 1770 1786 pcie->driver_data = (const struct kvaser_pciefd_driver_data *)id->driver_data; ··· 1775 1785 1776 1786 ret = pci_enable_device(pdev); 1777 1787 if (ret) 1778 - return ret; 1788 + goto err_free_devlink; 1779 1789 1780 1790 ret = pci_request_regions(pdev, KVASER_PCIEFD_DRV_NAME); 1781 1791 if (ret) ··· 1803 1813 1804 1814 ret = pci_alloc_irq_vectors(pcie->pci, 1, 1, PCI_IRQ_INTX | PCI_IRQ_MSI); 1805 1815 if (ret < 0) { 1806 - dev_err(&pcie->pci->dev, "Failed to allocate IRQ vectors.\n"); 1816 + dev_err(dev, "Failed to allocate IRQ vectors.\n"); 1807 1817 goto err_teardown_can_ctrls; 1808 1818 } 1809 1819 ··· 1816 1826 ret = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler, 1817 1827 IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie); 1818 1828 if (ret) { 1819 - dev_err(&pcie->pci->dev, "Failed to request IRQ %d\n", pcie->pci->irq); 1829 + dev_err(dev, "Failed to request IRQ %d\n", pcie->pci->irq); 1820 1830 goto err_pci_free_irq_vectors; 1821 1831 } 1822 1832 iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1, ··· 1838 1848 ret = kvaser_pciefd_reg_candev(pcie); 1839 1849 if (ret) 1840 1850 goto err_free_irq; 1851 + 1852 + devlink_register(devlink); 1841 1853 1842 1854 return 0; 1843 1855 ··· 1864 1872 err_disable_pci: 1865 1873 pci_disable_device(pdev); 1866 1874 1875 + err_free_devlink: 1876 + devlink_free(devlink); 1877 + 1867 1878 return ret; 1868 1879 } 1869 1880 ··· 1881 1886 unregister_candev(can->can.dev); 1882 1887 timer_delete(&can->bec_poll_timer); 1883 1888 kvaser_pciefd_pwm_stop(can); 1889 + kvaser_pciefd_devlink_port_unregister(can); 1884 1890 } 1885 1891 1886 1892 kvaser_pciefd_disable_irq_srcs(pcie); ··· 1891 1895 for (i = 0; i < pcie->nr_channels; ++i) 1892 1896 free_candev(pcie->can[i]->can.dev); 1893 1897 1898 + devlink_unregister(priv_to_devlink(pcie)); 1894 1899 pci_iounmap(pdev, pcie->reg_base); 1895 1900 pci_release_regions(pdev); 1896 1901 pci_disable_device(pdev); 1902 + devlink_free(priv_to_devlink(pcie)); 1897 1903 } 1898 1904 1899 1905 static struct pci_driver kvaser_pciefd = {
+3
drivers/net/can/kvaser_pciefd/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + obj-$(CONFIG_CAN_KVASER_PCIEFD) += kvaser_pciefd.o 3 + kvaser_pciefd-y = kvaser_pciefd_core.o kvaser_pciefd_devlink.o
+96
drivers/net/can/kvaser_pciefd/kvaser_pciefd.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ 2 + /* kvaser_pciefd common definitions and declarations 3 + * 4 + * Copyright (C) 2025 KVASER AB, Sweden. All rights reserved. 5 + */ 6 + 7 + #ifndef _KVASER_PCIEFD_H 8 + #define _KVASER_PCIEFD_H 9 + 10 + #include <linux/can/dev.h> 11 + #include <linux/completion.h> 12 + #include <linux/pci.h> 13 + #include <linux/spinlock.h> 14 + #include <linux/timer.h> 15 + #include <linux/types.h> 16 + #include <net/devlink.h> 17 + 18 + #define KVASER_PCIEFD_MAX_CAN_CHANNELS 8UL 19 + #define KVASER_PCIEFD_DMA_COUNT 2U 20 + #define KVASER_PCIEFD_DMA_SIZE (4U * 1024U) 21 + #define KVASER_PCIEFD_CAN_TX_MAX_COUNT 17U 22 + 23 + struct kvaser_pciefd; 24 + 25 + struct kvaser_pciefd_address_offset { 26 + u32 serdes; 27 + u32 pci_ien; 28 + u32 pci_irq; 29 + u32 sysid; 30 + u32 loopback; 31 + u32 kcan_srb_fifo; 32 + u32 kcan_srb; 33 + u32 kcan_ch0; 34 + u32 kcan_ch1; 35 + }; 36 + 37 + struct kvaser_pciefd_irq_mask { 38 + u32 kcan_rx0; 39 + u32 kcan_tx[KVASER_PCIEFD_MAX_CAN_CHANNELS]; 40 + u32 all; 41 + }; 42 + 43 + struct kvaser_pciefd_dev_ops { 44 + void (*kvaser_pciefd_write_dma_map)(struct kvaser_pciefd *pcie, 45 + dma_addr_t addr, int index); 46 + }; 47 + 48 + struct kvaser_pciefd_driver_data { 49 + const struct kvaser_pciefd_address_offset *address_offset; 50 + const struct kvaser_pciefd_irq_mask *irq_mask; 51 + const struct kvaser_pciefd_dev_ops *ops; 52 + }; 53 + 54 + struct kvaser_pciefd_fw_version { 55 + u8 major; 56 + u8 minor; 57 + u16 build; 58 + }; 59 + 60 + struct kvaser_pciefd_can { 61 + struct can_priv can; 62 + struct devlink_port devlink_port; 63 + struct kvaser_pciefd *kv_pcie; 64 + void __iomem *reg_base; 65 + struct can_berr_counter bec; 66 + u32 ioc; 67 + u8 cmd_seq; 68 + u8 tx_max_count; 69 + u8 tx_idx; 70 + u8 ack_idx; 71 + int err_rep_cnt; 72 + unsigned int completed_tx_pkts; 73 + unsigned int completed_tx_bytes; 74 + spinlock_t lock; /* Locks sensitive registers (e.g. MODE) */ 75 + struct timer_list bec_poll_timer; 76 + struct completion start_comp, flush_comp; 77 + }; 78 + 79 + struct kvaser_pciefd { 80 + struct pci_dev *pci; 81 + void __iomem *reg_base; 82 + struct kvaser_pciefd_can *can[KVASER_PCIEFD_MAX_CAN_CHANNELS]; 83 + const struct kvaser_pciefd_driver_data *driver_data; 84 + void *dma_data[KVASER_PCIEFD_DMA_COUNT]; 85 + u8 nr_channels; 86 + u32 bus_freq; 87 + u32 freq; 88 + u32 freq_to_ticks_div; 89 + struct kvaser_pciefd_fw_version fw_version; 90 + }; 91 + 92 + extern const struct devlink_ops kvaser_pciefd_devlink_ops; 93 + 94 + int kvaser_pciefd_devlink_port_register(struct kvaser_pciefd_can *can); 95 + void kvaser_pciefd_devlink_port_unregister(struct kvaser_pciefd_can *can); 96 + #endif /* _KVASER_PCIEFD_H */
+60
drivers/net/can/kvaser_pciefd/kvaser_pciefd_devlink.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + /* kvaser_pciefd devlink functions 3 + * 4 + * Copyright (C) 2025 KVASER AB, Sweden. All rights reserved. 5 + */ 6 + #include "kvaser_pciefd.h" 7 + 8 + #include <linux/netdevice.h> 9 + #include <net/devlink.h> 10 + 11 + static int kvaser_pciefd_devlink_info_get(struct devlink *devlink, 12 + struct devlink_info_req *req, 13 + struct netlink_ext_ack *extack) 14 + { 15 + struct kvaser_pciefd *pcie = devlink_priv(devlink); 16 + char buf[] = "xxx.xxx.xxxxx"; 17 + int ret; 18 + 19 + if (pcie->fw_version.major) { 20 + snprintf(buf, sizeof(buf), "%u.%u.%u", 21 + pcie->fw_version.major, 22 + pcie->fw_version.minor, 23 + pcie->fw_version.build); 24 + ret = devlink_info_version_running_put(req, 25 + DEVLINK_INFO_VERSION_GENERIC_FW, 26 + buf); 27 + if (ret) 28 + return ret; 29 + } 30 + 31 + return 0; 32 + } 33 + 34 + const struct devlink_ops kvaser_pciefd_devlink_ops = { 35 + .info_get = kvaser_pciefd_devlink_info_get, 36 + }; 37 + 38 + int kvaser_pciefd_devlink_port_register(struct kvaser_pciefd_can *can) 39 + { 40 + int ret; 41 + struct devlink_port_attrs attrs = { 42 + .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL, 43 + .phys.port_number = can->can.dev->dev_port, 44 + }; 45 + devlink_port_attrs_set(&can->devlink_port, &attrs); 46 + 47 + ret = devlink_port_register(priv_to_devlink(can->kv_pcie), 48 + &can->devlink_port, can->can.dev->dev_port); 49 + if (ret) 50 + return ret; 51 + 52 + SET_NETDEV_DEVLINK_PORT(can->can.dev, &can->devlink_port); 53 + 54 + return 0; 55 + } 56 + 57 + void kvaser_pciefd_devlink_port_unregister(struct kvaser_pciefd_can *can) 58 + { 59 + devlink_port_unregister(&can->devlink_port); 60 + }
+1 -1
drivers/net/can/sja1000/Kconfig
··· 105 105 106 106 config CAN_TSCAN1 107 107 tristate "TS-CAN1 PC104 boards" 108 - depends on ISA 108 + depends on (ISA && PC104) || (COMPILE_TEST && HAS_IOPORT) 109 109 help 110 110 This driver is for Technologic Systems' TSCAN-1 PC104 boards. 111 111 https://www.embeddedts.com/products/TS-CAN1
+1 -1
drivers/net/can/ti_hecc.c
··· 383 383 * overflows instead of the hardware silently dropping the 384 384 * messages. 385 385 */ 386 - mbx_mask = ~BIT(HECC_RX_LAST_MBOX); 386 + mbx_mask = ~BIT_U32(HECC_RX_LAST_MBOX); 387 387 hecc_write(priv, HECC_CANOPC, mbx_mask); 388 388 389 389 /* Enable interrupts */
+1
drivers/net/can/usb/Kconfig
··· 66 66 67 67 config CAN_KVASER_USB 68 68 tristate "Kvaser CAN/USB interface" 69 + select NET_DEVLINK 69 70 help 70 71 This driver adds support for Kvaser CAN/USB devices like Kvaser 71 72 Leaf Light, Kvaser USBcan II and Kvaser Memorator Pro 5xHS.
+1 -1
drivers/net/can/usb/kvaser_usb/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o 3 - kvaser_usb-y = kvaser_usb_core.o kvaser_usb_leaf.o kvaser_usb_hydra.o 3 + kvaser_usb-y = kvaser_usb_core.o kvaser_usb_devlink.o kvaser_usb_leaf.o kvaser_usb_hydra.o
+31 -2
drivers/net/can/usb/kvaser_usb/kvaser_usb.h
··· 27 27 #include <linux/spinlock.h> 28 28 #include <linux/types.h> 29 29 #include <linux/usb.h> 30 + #include <net/devlink.h> 30 31 31 32 #include <linux/can.h> 32 33 #include <linux/can/dev.h> ··· 48 47 #define KVASER_USB_CAP_EXT_CAP 0x02 49 48 #define KVASER_USB_HYDRA_CAP_EXT_CMD 0x04 50 49 50 + #define KVASER_USB_SW_VERSION_MAJOR_MASK GENMASK(31, 24) 51 + #define KVASER_USB_SW_VERSION_MINOR_MASK GENMASK(23, 16) 52 + #define KVASER_USB_SW_VERSION_BUILD_MASK GENMASK(15, 0) 53 + 51 54 struct kvaser_usb_dev_cfg; 52 55 53 56 enum kvaser_usb_leaf_family { 54 57 KVASER_LEAF, 55 58 KVASER_USBCAN, 59 + }; 60 + 61 + enum kvaser_usb_led_state { 62 + KVASER_USB_LED_ON = 0, 63 + KVASER_USB_LED_OFF = 1, 56 64 }; 57 65 58 66 #define KVASER_USB_HYDRA_MAX_CMD_LEN 128 ··· 88 78 u32 echo_index; 89 79 }; 90 80 81 + struct kvaser_usb_fw_version { 82 + u8 major; 83 + u8 minor; 84 + u16 build; 85 + }; 86 + 91 87 struct kvaser_usb_busparams { 92 88 __le32 bitrate; 93 89 u8 tseg1; ··· 112 96 struct usb_endpoint_descriptor *bulk_in, *bulk_out; 113 97 struct usb_anchor rx_submitted; 114 98 99 + u32 ean[2]; 100 + u32 serial_number; 101 + struct kvaser_usb_fw_version fw_version; 102 + u8 hw_revision; 103 + unsigned int nchannels; 115 104 /* @max_tx_urbs: Firmware-reported maximum number of outstanding, 116 105 * not yet ACKed, transmissions on this device. This value is 117 106 * also used as a sentinel for marking free tx contexts. 118 107 */ 119 - u32 fw_version; 120 - unsigned int nchannels; 121 108 unsigned int max_tx_urbs; 122 109 struct kvaser_usb_dev_card_data card_data; 123 110 ··· 131 112 132 113 struct kvaser_usb_net_priv { 133 114 struct can_priv can; 115 + struct devlink_port devlink_port; 134 116 struct can_berr_counter bec; 135 117 136 118 /* subdriver-specific data */ ··· 169 149 * @dev_get_software_details: get software details 170 150 * @dev_get_card_info: get card info 171 151 * @dev_get_capabilities: discover device capabilities 152 + * @dev_set_led: turn on/off device LED 172 153 * 173 154 * @dev_set_opt_mode: set ctrlmod 174 155 * @dev_start_chip: start the CAN controller ··· 197 176 int (*dev_get_software_details)(struct kvaser_usb *dev); 198 177 int (*dev_get_card_info)(struct kvaser_usb *dev); 199 178 int (*dev_get_capabilities)(struct kvaser_usb *dev); 179 + int (*dev_set_led)(struct kvaser_usb_net_priv *priv, 180 + enum kvaser_usb_led_state state, 181 + u16 duration_ms); 200 182 int (*dev_set_opt_mode)(const struct kvaser_usb_net_priv *priv); 201 183 int (*dev_start_chip)(struct kvaser_usb_net_priv *priv); 202 184 int (*dev_stop_chip)(struct kvaser_usb_net_priv *priv); ··· 227 203 228 204 extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; 229 205 extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; 206 + 207 + extern const struct devlink_ops kvaser_usb_devlink_ops; 208 + 209 + int kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv *priv); 210 + void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv); 230 211 231 212 void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); 232 213
+99 -40
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
··· 364 364 err = usb_submit_urb(urb, GFP_ATOMIC); 365 365 if (err == -ENODEV) { 366 366 for (i = 0; i < dev->nchannels; i++) { 367 - if (!dev->nets[i]) 367 + struct kvaser_usb_net_priv *priv; 368 + 369 + priv = dev->nets[i]; 370 + if (!priv) 368 371 continue; 369 372 370 - netif_device_detach(dev->nets[i]->netdev); 373 + netif_device_detach(priv->netdev); 371 374 } 372 375 } else if (err) { 373 376 dev_err(&dev->intf->dev, ··· 756 753 return ret; 757 754 } 758 755 756 + static int kvaser_usb_set_phys_id(struct net_device *netdev, 757 + enum ethtool_phys_id_state state) 758 + { 759 + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); 760 + const struct kvaser_usb_dev_ops *ops = priv->dev->driver_info->ops; 761 + 762 + switch (state) { 763 + case ETHTOOL_ID_ACTIVE: 764 + return 3; /* 3 On/Off cycles per second */ 765 + 766 + case ETHTOOL_ID_ON: 767 + return ops->dev_set_led(priv, KVASER_USB_LED_ON, 1000); 768 + 769 + case ETHTOOL_ID_OFF: 770 + return ops->dev_set_led(priv, KVASER_USB_LED_OFF, 1000); 771 + 772 + case ETHTOOL_ID_INACTIVE: 773 + /* Turn LED off and restore standard function after 1ms */ 774 + return ops->dev_set_led(priv, KVASER_USB_LED_OFF, 1); 775 + 776 + default: 777 + return -EINVAL; 778 + } 779 + } 780 + 759 781 static const struct net_device_ops kvaser_usb_netdev_ops = { 760 782 .ndo_open = kvaser_usb_open, 761 783 .ndo_stop = kvaser_usb_close, ··· 791 763 792 764 static const struct ethtool_ops kvaser_usb_ethtool_ops = { 793 765 .get_ts_info = can_ethtool_op_get_ts_info_hwts, 766 + .set_phys_id = kvaser_usb_set_phys_id, 794 767 }; 795 768 796 769 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) 797 770 { 798 771 const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; 799 772 int i; 773 + struct kvaser_usb_net_priv *priv; 800 774 801 775 for (i = 0; i < dev->nchannels; i++) { 802 - if (!dev->nets[i]) 776 + priv = dev->nets[i]; 777 + if (!priv) 803 778 continue; 804 779 805 - unregister_candev(dev->nets[i]->netdev); 780 + unregister_candev(priv->netdev); 806 781 } 807 782 808 783 kvaser_usb_unlink_all_urbs(dev); 809 784 810 785 for (i = 0; i < dev->nchannels; i++) { 811 - if (!dev->nets[i]) 786 + priv = dev->nets[i]; 787 + if (!priv) 812 788 continue; 813 789 814 790 if (ops->dev_remove_channel) 815 - ops->dev_remove_channel(dev->nets[i]); 791 + ops->dev_remove_channel(priv); 816 792 817 - free_candev(dev->nets[i]->netdev); 793 + kvaser_usb_devlink_port_unregister(priv); 794 + free_candev(priv->netdev); 818 795 } 819 796 } 820 797 ··· 885 852 netdev->ethtool_ops = &kvaser_usb_ethtool_ops; 886 853 SET_NETDEV_DEV(netdev, &dev->intf->dev); 887 854 netdev->dev_id = channel; 855 + netdev->dev_port = channel; 888 856 889 857 dev->nets[channel] = priv; 890 858 891 859 if (ops->dev_init_channel) { 892 860 err = ops->dev_init_channel(priv); 893 861 if (err) 894 - goto err; 862 + goto candev_free; 863 + } 864 + 865 + err = kvaser_usb_devlink_port_register(priv); 866 + if (err) { 867 + dev_err(&dev->intf->dev, "Failed to register devlink port\n"); 868 + goto candev_free; 895 869 } 896 870 897 871 err = register_candev(netdev); 898 872 if (err) { 899 873 dev_err(&dev->intf->dev, "Failed to register CAN device\n"); 900 - goto err; 874 + goto unregister_devlink_port; 901 875 } 902 876 903 877 netdev_dbg(netdev, "device registered\n"); 904 878 905 879 return 0; 906 880 907 - err: 881 + unregister_devlink_port: 882 + kvaser_usb_devlink_port_unregister(priv); 883 + candev_free: 908 884 free_candev(netdev); 909 885 dev->nets[channel] = NULL; 910 886 return err; ··· 923 881 const struct usb_device_id *id) 924 882 { 925 883 struct kvaser_usb *dev; 884 + struct devlink *devlink; 926 885 int err; 927 886 int i; 928 887 const struct kvaser_usb_driver_info *driver_info; ··· 933 890 if (!driver_info) 934 891 return -ENODEV; 935 892 936 - dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); 937 - if (!dev) 893 + devlink = devlink_alloc(&kvaser_usb_devlink_ops, sizeof(*dev), &intf->dev); 894 + if (!devlink) 938 895 return -ENOMEM; 939 896 897 + dev = devlink_priv(devlink); 940 898 dev->intf = intf; 941 899 dev->driver_info = driver_info; 942 900 ops = driver_info->ops; 943 901 944 902 err = ops->dev_setup_endpoints(dev); 945 - if (err) 946 - return dev_err_probe(&intf->dev, err, "Cannot get usb endpoint(s)"); 903 + if (err) { 904 + dev_err_probe(&intf->dev, err, "Cannot get usb endpoint(s)"); 905 + goto free_devlink; 906 + } 947 907 948 908 dev->udev = interface_to_usbdev(intf); 949 909 ··· 957 911 dev->card_data.ctrlmode_supported = 0; 958 912 dev->card_data.capabilities = 0; 959 913 err = ops->dev_init_card(dev); 960 - if (err) 961 - return dev_err_probe(&intf->dev, err, 962 - "Failed to initialize card\n"); 914 + if (err) { 915 + dev_err_probe(&intf->dev, err, 916 + "Failed to initialize card\n"); 917 + goto free_devlink; 918 + } 963 919 964 920 err = ops->dev_get_software_info(dev); 965 - if (err) 966 - return dev_err_probe(&intf->dev, err, 967 - "Cannot get software info\n"); 921 + if (err) { 922 + dev_err_probe(&intf->dev, err, 923 + "Cannot get software info\n"); 924 + goto free_devlink; 925 + } 968 926 969 927 if (ops->dev_get_software_details) { 970 928 err = ops->dev_get_software_details(dev); 971 - if (err) 972 - return dev_err_probe(&intf->dev, err, 973 - "Cannot get software details\n"); 929 + if (err) { 930 + dev_err_probe(&intf->dev, err, 931 + "Cannot get software details\n"); 932 + goto free_devlink; 933 + } 974 934 } 975 935 976 - if (WARN_ON(!dev->cfg)) 977 - return -ENODEV; 978 - 979 - dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n", 980 - ((dev->fw_version >> 24) & 0xff), 981 - ((dev->fw_version >> 16) & 0xff), 982 - (dev->fw_version & 0xffff)); 936 + if (WARN_ON(!dev->cfg)) { 937 + err = -ENODEV; 938 + goto free_devlink; 939 + } 983 940 984 941 dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); 985 942 986 943 err = ops->dev_get_card_info(dev); 987 - if (err) 988 - return dev_err_probe(&intf->dev, err, 989 - "Cannot get card info\n"); 944 + if (err) { 945 + dev_err_probe(&intf->dev, err, 946 + "Cannot get card info\n"); 947 + goto free_devlink; 948 + } 990 949 991 950 if (ops->dev_get_capabilities) { 992 951 err = ops->dev_get_capabilities(dev); 993 952 if (err) { 994 - kvaser_usb_remove_interfaces(dev); 995 - return dev_err_probe(&intf->dev, err, 996 - "Cannot get capabilities\n"); 953 + dev_err_probe(&intf->dev, err, 954 + "Cannot get capabilities\n"); 955 + goto remove_interfaces; 997 956 } 998 957 } 999 958 1000 959 for (i = 0; i < dev->nchannels; i++) { 1001 960 err = kvaser_usb_init_one(dev, i); 1002 - if (err) { 1003 - kvaser_usb_remove_interfaces(dev); 1004 - return err; 1005 - } 961 + if (err) 962 + goto remove_interfaces; 1006 963 } 964 + devlink_register(devlink); 1007 965 1008 966 return 0; 967 + 968 + remove_interfaces: 969 + kvaser_usb_remove_interfaces(dev); 970 + free_devlink: 971 + devlink_free(devlink); 972 + 973 + return err; 1009 974 } 1010 975 1011 976 static void kvaser_usb_disconnect(struct usb_interface *intf) ··· 1029 972 return; 1030 973 1031 974 kvaser_usb_remove_interfaces(dev); 975 + devlink_unregister(priv_to_devlink(dev)); 976 + devlink_free(priv_to_devlink(dev)); 1032 977 } 1033 978 1034 979 static struct usb_driver kvaser_usb_driver = {
+87
drivers/net/can/usb/kvaser_usb/kvaser_usb_devlink.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* kvaser_usb devlink functions 3 + * 4 + * Copyright (C) 2025 KVASER AB, Sweden. All rights reserved. 5 + */ 6 + #include "kvaser_usb.h" 7 + 8 + #include <linux/netdevice.h> 9 + #include <net/devlink.h> 10 + 11 + #define KVASER_USB_EAN_MSB 0x00073301 12 + 13 + static int kvaser_usb_devlink_info_get(struct devlink *devlink, 14 + struct devlink_info_req *req, 15 + struct netlink_ext_ack *extack) 16 + { 17 + struct kvaser_usb *dev = devlink_priv(devlink); 18 + char buf[] = "73301XXXXXXXXXX"; 19 + int ret; 20 + 21 + if (dev->serial_number) { 22 + snprintf(buf, sizeof(buf), "%u", dev->serial_number); 23 + ret = devlink_info_serial_number_put(req, buf); 24 + if (ret) 25 + return ret; 26 + } 27 + 28 + if (dev->fw_version.major) { 29 + snprintf(buf, sizeof(buf), "%u.%u.%u", 30 + dev->fw_version.major, 31 + dev->fw_version.minor, 32 + dev->fw_version.build); 33 + ret = devlink_info_version_running_put(req, 34 + DEVLINK_INFO_VERSION_GENERIC_FW, 35 + buf); 36 + if (ret) 37 + return ret; 38 + } 39 + 40 + if (dev->hw_revision) { 41 + snprintf(buf, sizeof(buf), "%u", dev->hw_revision); 42 + ret = devlink_info_version_fixed_put(req, 43 + DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, 44 + buf); 45 + if (ret) 46 + return ret; 47 + } 48 + 49 + if (dev->ean[1] == KVASER_USB_EAN_MSB) { 50 + snprintf(buf, sizeof(buf), "%x%08x", dev->ean[1], dev->ean[0]); 51 + ret = devlink_info_version_fixed_put(req, 52 + DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, 53 + buf); 54 + if (ret) 55 + return ret; 56 + } 57 + 58 + return 0; 59 + } 60 + 61 + const struct devlink_ops kvaser_usb_devlink_ops = { 62 + .info_get = kvaser_usb_devlink_info_get, 63 + }; 64 + 65 + int kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv *priv) 66 + { 67 + int ret; 68 + struct devlink_port_attrs attrs = { 69 + .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL, 70 + .phys.port_number = priv->channel, 71 + }; 72 + devlink_port_attrs_set(&priv->devlink_port, &attrs); 73 + 74 + ret = devlink_port_register(priv_to_devlink(priv->dev), 75 + &priv->devlink_port, priv->channel); 76 + if (ret) 77 + return ret; 78 + 79 + SET_NETDEV_DEVLINK_PORT(priv->netdev, &priv->devlink_port); 80 + 81 + return 0; 82 + } 83 + 84 + void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv) 85 + { 86 + devlink_port_unregister(&priv->devlink_port); 87 + }
+63 -2
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
··· 12 12 * distinguish between ERROR_WARNING and ERROR_ACTIVE. 13 13 */ 14 14 15 + #include <linux/bitfield.h> 15 16 #include <linux/completion.h> 16 17 #include <linux/device.h> 17 18 #include <linux/gfp.h> ··· 68 67 #define CMD_SET_BUSPARAMS_RESP 85 69 68 #define CMD_GET_CAPABILITIES_REQ 95 70 69 #define CMD_GET_CAPABILITIES_RESP 96 70 + #define CMD_LED_ACTION_REQ 101 71 + #define CMD_LED_ACTION_RESP 102 71 72 #define CMD_RX_MESSAGE 106 72 73 #define CMD_MAP_CHANNEL_REQ 200 73 74 #define CMD_MAP_CHANNEL_RESP 201 ··· 114 111 __le32 clock_res; 115 112 __le32 mfg_date; 116 113 __le32 ean[2]; 117 - u8 hw_version; 114 + u8 hw_revision; 118 115 u8 usb_mode; 119 116 u8 hw_type; 120 117 u8 reserved0; ··· 220 217 u8 reserved[20]; 221 218 } __packed; 222 219 220 + /* The device has two LEDs per CAN channel 221 + * The LSB of action field controls the state: 222 + * 0 = ON 223 + * 1 = OFF 224 + * The remaining bits of action field is the LED index 225 + */ 226 + #define KVASER_USB_HYDRA_LED_IDX_MASK GENMASK(31, 1) 227 + #define KVASER_USB_HYDRA_LED_YELLOW_CH0_IDX 3 228 + #define KVASER_USB_HYDRA_LEDS_PER_CHANNEL 2 229 + struct kvaser_cmd_led_action_req { 230 + u8 action; 231 + u8 padding; 232 + __le16 duration_ms; 233 + u8 reserved[24]; 234 + } __packed; 235 + 223 236 /* Ctrl modes */ 224 237 #define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01 225 238 #define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02 ··· 317 298 struct kvaser_cmd_set_busparams set_busparams_req; 318 299 struct kvaser_cmd_get_busparams_req get_busparams_req; 319 300 struct kvaser_cmd_get_busparams_res get_busparams_res; 301 + 302 + struct kvaser_cmd_led_action_req led_action_req; 320 303 321 304 struct kvaser_cmd_chip_state_event chip_state_event; 322 305 ··· 1411 1390 /* Ignored commands */ 1412 1391 case CMD_SET_BUSPARAMS_RESP: 1413 1392 case CMD_SET_BUSPARAMS_FD_RESP: 1393 + case CMD_LED_ACTION_RESP: 1414 1394 break; 1415 1395 1416 1396 default: ··· 1839 1817 size_t cmd_len; 1840 1818 int err; 1841 1819 u32 flags; 1820 + u32 fw_version; 1842 1821 struct kvaser_usb_dev_card_data *card_data = &dev->card_data; 1843 1822 1844 1823 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ··· 1864 1841 if (err) 1865 1842 goto end; 1866 1843 1867 - dev->fw_version = le32_to_cpu(cmd->sw_detail_res.sw_version); 1844 + fw_version = le32_to_cpu(cmd->sw_detail_res.sw_version); 1845 + dev->fw_version.major = FIELD_GET(KVASER_USB_SW_VERSION_MAJOR_MASK, fw_version); 1846 + dev->fw_version.minor = FIELD_GET(KVASER_USB_SW_VERSION_MINOR_MASK, fw_version); 1847 + dev->fw_version.build = FIELD_GET(KVASER_USB_SW_VERSION_BUILD_MASK, fw_version); 1868 1848 flags = le32_to_cpu(cmd->sw_detail_res.sw_flags); 1869 1849 1870 1850 if (flags & KVASER_USB_HYDRA_SW_FLAG_FW_BAD) { ··· 1918 1892 err = kvaser_usb_hydra_wait_cmd(dev, CMD_GET_CARD_INFO_RESP, &cmd); 1919 1893 if (err) 1920 1894 return err; 1895 + dev->ean[1] = le32_to_cpu(cmd.card_info.ean[1]); 1896 + dev->ean[0] = le32_to_cpu(cmd.card_info.ean[0]); 1897 + dev->serial_number = le32_to_cpu(cmd.card_info.serial_number); 1898 + dev->hw_revision = cmd.card_info.hw_revision; 1921 1899 1922 1900 dev->nchannels = cmd.card_info.nchannels; 1923 1901 if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES) ··· 1974 1944 status); 1975 1945 1976 1946 return 0; 1947 + } 1948 + 1949 + static int kvaser_usb_hydra_set_led(struct kvaser_usb_net_priv *priv, 1950 + enum kvaser_usb_led_state state, 1951 + u16 duration_ms) 1952 + { 1953 + struct kvaser_usb *dev = priv->dev; 1954 + struct kvaser_cmd *cmd; 1955 + size_t cmd_len; 1956 + int ret; 1957 + 1958 + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1959 + if (!cmd) 1960 + return -ENOMEM; 1961 + 1962 + cmd->header.cmd_no = CMD_LED_ACTION_REQ; 1963 + cmd_len = kvaser_usb_hydra_cmd_size(cmd); 1964 + kvaser_usb_hydra_set_cmd_dest_he(cmd, dev->card_data.hydra.sysdbg_he); 1965 + kvaser_usb_hydra_set_cmd_transid(cmd, kvaser_usb_hydra_get_next_transid(dev)); 1966 + 1967 + cmd->led_action_req.duration_ms = cpu_to_le16(duration_ms); 1968 + cmd->led_action_req.action = state | 1969 + FIELD_PREP(KVASER_USB_HYDRA_LED_IDX_MASK, 1970 + KVASER_USB_HYDRA_LED_YELLOW_CH0_IDX + 1971 + KVASER_USB_HYDRA_LEDS_PER_CHANNEL * priv->channel); 1972 + 1973 + ret = kvaser_usb_send_cmd(dev, cmd, cmd_len); 1974 + kfree(cmd); 1975 + 1976 + return ret; 1977 1977 } 1978 1978 1979 1979 static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv) ··· 2209 2149 .dev_get_software_details = kvaser_usb_hydra_get_software_details, 2210 2150 .dev_get_card_info = kvaser_usb_hydra_get_card_info, 2211 2151 .dev_get_capabilities = kvaser_usb_hydra_get_capabilities, 2152 + .dev_set_led = kvaser_usb_hydra_set_led, 2212 2153 .dev_set_opt_mode = kvaser_usb_hydra_set_opt_mode, 2213 2154 .dev_start_chip = kvaser_usb_hydra_start_chip, 2214 2155 .dev_stop_chip = kvaser_usb_hydra_stop_chip,
+72 -3
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
··· 10 10 * Copyright (C) 2015 Valeo S.A. 11 11 */ 12 12 13 + #include <linux/bitfield.h> 13 14 #include <linux/completion.h> 14 15 #include <linux/device.h> 15 16 #include <linux/gfp.h> ··· 82 81 #define CMD_FLUSH_QUEUE_REPLY 68 83 82 #define CMD_GET_CAPABILITIES_REQ 95 84 83 #define CMD_GET_CAPABILITIES_RESP 96 84 + #define CMD_LED_ACTION_REQ 101 85 + #define CMD_LED_ACTION_RESP 102 85 86 86 87 #define CMD_LEAF_LOG_MESSAGE 106 87 88 ··· 138 135 __le32 padding0; 139 136 __le32 clock_resolution; 140 137 __le32 mfgdate; 141 - u8 ean[8]; 138 + __le32 ean[2]; 142 139 u8 hw_revision; 143 140 union { 144 141 struct { ··· 174 171 u8 tid; 175 172 u8 channel; 176 173 struct kvaser_usb_busparams busparams; 174 + } __packed; 175 + 176 + /* The device has one LED per CAN channel 177 + * The LSB of action field controls the state: 178 + * 0 = ON 179 + * 1 = OFF 180 + * The remaining bits of action field is the LED index 181 + */ 182 + #define KVASER_USB_LEAF_LED_IDX_MASK GENMASK(31, 1) 183 + #define KVASER_USB_LEAF_LED_YELLOW_CH0_IDX 2 184 + struct kvaser_cmd_led_action_req { 185 + u8 tid; 186 + u8 action; 187 + __le16 duration_ms; 188 + u8 padding[24]; 177 189 } __packed; 178 190 179 191 struct kvaser_cmd_tx_can { ··· 377 359 struct kvaser_cmd_cardinfo cardinfo; 378 360 struct kvaser_cmd_busparams busparams; 379 361 362 + struct kvaser_cmd_led_action_req led_action_req; 363 + 380 364 struct kvaser_cmd_rx_can_header rx_can_header; 381 365 struct kvaser_cmd_tx_acknowledge_header tx_acknowledge_header; 382 366 ··· 429 409 [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), 430 410 /* ignored events: */ 431 411 [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, 412 + [CMD_LED_ACTION_RESP] = CMD_SIZE_ANY, 432 413 }; 433 414 434 415 static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { ··· 444 423 [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), 445 424 [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), 446 425 [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = kvaser_fsize(u.usbcan.clk_overflow_event), 426 + /* ignored events: */ 427 + [CMD_LED_ACTION_RESP] = CMD_SIZE_ANY, 447 428 }; 448 429 449 430 /* Summary of a kvaser error event, for a unified Leaf/Usbcan error ··· 741 718 static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, 742 719 const struct leaf_cmd_softinfo *softinfo) 743 720 { 721 + u32 fw_version; 744 722 u32 sw_options = le32_to_cpu(softinfo->sw_options); 745 723 746 - dev->fw_version = le32_to_cpu(softinfo->fw_version); 724 + fw_version = le32_to_cpu(softinfo->fw_version); 725 + dev->fw_version.major = FIELD_GET(KVASER_USB_SW_VERSION_MAJOR_MASK, fw_version); 726 + dev->fw_version.minor = FIELD_GET(KVASER_USB_SW_VERSION_MINOR_MASK, fw_version); 727 + dev->fw_version.build = FIELD_GET(KVASER_USB_SW_VERSION_BUILD_MASK, fw_version); 747 728 dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); 748 729 749 730 if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP) ··· 788 761 { 789 762 struct kvaser_cmd cmd; 790 763 int err; 764 + u32 fw_version; 791 765 792 766 err = kvaser_usb_leaf_send_simple_cmd(dev, CMD_GET_SOFTWARE_INFO, 0); 793 767 if (err) ··· 803 775 kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); 804 776 break; 805 777 case KVASER_USBCAN: 806 - dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); 778 + fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); 779 + dev->fw_version.major = FIELD_GET(KVASER_USB_SW_VERSION_MAJOR_MASK, 780 + fw_version); 781 + dev->fw_version.minor = FIELD_GET(KVASER_USB_SW_VERSION_MINOR_MASK, 782 + fw_version); 783 + dev->fw_version.build = FIELD_GET(KVASER_USB_SW_VERSION_BUILD_MASK, 784 + fw_version); 807 785 dev->max_tx_urbs = 808 786 le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); 809 787 dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg; ··· 854 820 (dev->driver_info->family == KVASER_USBCAN && 855 821 dev->nchannels > MAX_USBCAN_NET_DEVICES)) 856 822 return -EINVAL; 823 + dev->ean[1] = le32_to_cpu(cmd.u.cardinfo.ean[1]); 824 + dev->ean[0] = le32_to_cpu(cmd.u.cardinfo.ean[0]); 825 + dev->serial_number = le32_to_cpu(cmd.u.cardinfo.serial_number); 826 + dev->hw_revision = cmd.u.cardinfo.hw_revision; 857 827 858 828 return 0; 859 829 } ··· 960 922 status); 961 923 962 924 return 0; 925 + } 926 + 927 + static int kvaser_usb_leaf_set_led(struct kvaser_usb_net_priv *priv, 928 + enum kvaser_usb_led_state state, 929 + u16 duration_ms) 930 + { 931 + struct kvaser_usb *dev = priv->dev; 932 + struct kvaser_cmd *cmd; 933 + int ret; 934 + 935 + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 936 + if (!cmd) 937 + return -ENOMEM; 938 + 939 + cmd->id = CMD_LED_ACTION_REQ; 940 + cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_led_action_req); 941 + cmd->u.led_action_req.tid = 0xff; 942 + 943 + cmd->u.led_action_req.duration_ms = cpu_to_le16(duration_ms); 944 + cmd->u.led_action_req.action = state | 945 + FIELD_PREP(KVASER_USB_LEAF_LED_IDX_MASK, 946 + KVASER_USB_LEAF_LED_YELLOW_CH0_IDX + 947 + priv->channel); 948 + 949 + ret = kvaser_usb_send_cmd(dev, cmd, cmd->len); 950 + kfree(cmd); 951 + 952 + return ret; 963 953 } 964 954 965 955 static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev) ··· 1704 1638 if (dev->driver_info->family != KVASER_LEAF) 1705 1639 goto warn; 1706 1640 break; 1641 + case CMD_LED_ACTION_RESP: 1642 + break; 1707 1643 1708 1644 default: 1709 1645 warn: dev_warn(&dev->intf->dev, "Unhandled command (%d)\n", cmd->id); ··· 1995 1927 .dev_get_software_details = NULL, 1996 1928 .dev_get_card_info = kvaser_usb_leaf_get_card_info, 1997 1929 .dev_get_capabilities = kvaser_usb_leaf_get_capabilities, 1930 + .dev_set_led = kvaser_usb_leaf_set_led, 1998 1931 .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode, 1999 1932 .dev_start_chip = kvaser_usb_leaf_start_chip, 2000 1933 .dev_stop_chip = kvaser_usb_leaf_stop_chip,