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

Configure Feed

Select the types of activity you want to include in your feed.

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

Marc Kleine-Budde says:

====================
pull-request: can-next 2024-06-29

Geert Uytterhoeven contributes 3 patches with small improvements and
cleanups for the rcar_canfd driver.

A patch by Christophe JAILLET constifies the struct m_can_ops in the
m_can driver to reduce the code size.

The last 9 patches are by me an work around erratum DS80000789E 6 of
mcp2518fd.

* tag 'linux-can-next-for-6.11-20240629' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of mcp2518fd
can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index erratum
can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd
can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum
can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in separate function
can: mcp251xfd: clarify the meaning of timestamp
can: mcp251xfd: move mcp251xfd_timestamp_start()/stop() into mcp251xfd_chip_start/stop()
can: mcp251xfd: update errata references
can: mcp251xfd: properly indent labels
can: gs_usb: add VID/PID for Xylanta SAINT3 product family
can: m_can: Constify struct m_can_ops
can: rcar_canfd: Remove superfluous parentheses in address calculations
can: rcar_canfd: Improve printing of global operational state
can: rcar_canfd: Simplify clock handling
====================

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

+294 -230
+1 -1
drivers/net/can/m_can/m_can.h
··· 91 91 92 92 ktime_t irq_timer_wait; 93 93 94 - struct m_can_ops *ops; 94 + const struct m_can_ops *ops; 95 95 96 96 int version; 97 97 u32 irqstatus;
+1 -1
drivers/net/can/m_can/m_can_pci.c
··· 77 77 return 0; 78 78 } 79 79 80 - static struct m_can_ops m_can_pci_ops = { 80 + static const struct m_can_ops m_can_pci_ops = { 81 81 .read_reg = iomap_read_reg, 82 82 .write_reg = iomap_write_reg, 83 83 .write_fifo = iomap_write_fifo,
+1 -1
drivers/net/can/m_can/m_can_platform.c
··· 68 68 return 0; 69 69 } 70 70 71 - static struct m_can_ops m_can_plat_ops = { 71 + static const struct m_can_ops m_can_plat_ops = { 72 72 .read_reg = iomap_read_reg, 73 73 .write_reg = iomap_write_reg, 74 74 .write_fifo = iomap_write_fifo,
+1 -1
drivers/net/can/m_can/tcan4x5x-core.c
··· 357 357 return 0; 358 358 } 359 359 360 - static struct m_can_ops tcan4x5x_ops = { 360 + static const struct m_can_ops tcan4x5x_ops = { 361 361 .init = tcan4x5x_init, 362 362 .read_reg = tcan4x5x_read_reg, 363 363 .write_reg = tcan4x5x_write_reg,
+16 -25
drivers/net/can/rcar/rcar_canfd.c
··· 508 508 */ 509 509 #define RCANFD_CFFIFO_IDX 0 510 510 511 - /* fCAN clock select register settings */ 512 - enum rcar_canfd_fcanclk { 513 - RCANFD_CANFDCLK = 0, /* CANFD clock */ 514 - RCANFD_EXTCLK, /* Externally input clock */ 515 - }; 516 - 517 511 struct rcar_canfd_global; 518 512 519 513 struct rcar_canfd_hw_info { ··· 539 545 struct platform_device *pdev; /* Respective platform device */ 540 546 struct clk *clkp; /* Peripheral clock */ 541 547 struct clk *can_clk; /* fCAN clock */ 542 - enum rcar_canfd_fcanclk fcan; /* CANFD or Ext clock */ 543 548 unsigned long channels_mask; /* Enabled channels mask */ 549 + bool extclk; /* CANFD or Ext clock */ 544 550 bool fdmode; /* CAN FD or Classical CAN only mode */ 545 551 struct reset_control *rstc1; 546 552 struct reset_control *rstc2; ··· 627 633 628 634 static inline u32 rcar_canfd_read(void __iomem *base, u32 offset) 629 635 { 630 - return readl(base + (offset)); 636 + return readl(base + offset); 631 637 } 632 638 633 639 static inline void rcar_canfd_write(void __iomem *base, u32 offset, u32 val) 634 640 { 635 - writel(val, base + (offset)); 641 + writel(val, base + offset); 636 642 } 637 643 638 644 static void rcar_canfd_set_bit(void __iomem *base, u32 reg, u32 val) 639 645 { 640 - rcar_canfd_update(val, val, base + (reg)); 646 + rcar_canfd_update(val, val, base + reg); 641 647 } 642 648 643 649 static void rcar_canfd_clear_bit(void __iomem *base, u32 reg, u32 val) 644 650 { 645 - rcar_canfd_update(val, 0, base + (reg)); 651 + rcar_canfd_update(val, 0, base + reg); 646 652 } 647 653 648 654 static void rcar_canfd_update_bit(void __iomem *base, u32 reg, 649 655 u32 mask, u32 val) 650 656 { 651 - rcar_canfd_update(mask, val, base + (reg)); 657 + rcar_canfd_update(mask, val, base + reg); 652 658 } 653 659 654 660 static void rcar_canfd_get_data(struct rcar_canfd_channel *priv, ··· 659 665 lwords = DIV_ROUND_UP(cf->len, sizeof(u32)); 660 666 for (i = 0; i < lwords; i++) 661 667 *((u32 *)cf->data + i) = 662 - rcar_canfd_read(priv->base, off + (i * sizeof(u32))); 668 + rcar_canfd_read(priv->base, off + i * sizeof(u32)); 663 669 } 664 670 665 671 static void rcar_canfd_put_data(struct rcar_canfd_channel *priv, ··· 669 675 670 676 lwords = DIV_ROUND_UP(cf->len, sizeof(u32)); 671 677 for (i = 0; i < lwords; i++) 672 - rcar_canfd_write(priv->base, off + (i * sizeof(u32)), 678 + rcar_canfd_write(priv->base, off + i * sizeof(u32), 673 679 *((u32 *)cf->data + i)); 674 680 } 675 681 ··· 771 777 cfg |= RCANFD_GCFG_CMPOC; 772 778 773 779 /* Set External Clock if selected */ 774 - if (gpriv->fcan != RCANFD_CANFDCLK) 780 + if (gpriv->extclk) 775 781 cfg |= RCANFD_GCFG_DCS; 776 782 777 783 rcar_canfd_set_bit(gpriv->base, RCANFD_GCFG, cfg); ··· 1935 1941 return dev_err_probe(dev, PTR_ERR(gpriv->can_clk), 1936 1942 "cannot get canfd clock\n"); 1937 1943 1938 - gpriv->fcan = RCANFD_CANFDCLK; 1939 - 1944 + /* CANFD clock may be further divided within the IP */ 1945 + fcan_freq = clk_get_rate(gpriv->can_clk) / info->postdiv; 1940 1946 } else { 1941 - gpriv->fcan = RCANFD_EXTCLK; 1947 + fcan_freq = clk_get_rate(gpriv->can_clk); 1948 + gpriv->extclk = true; 1942 1949 } 1943 - fcan_freq = clk_get_rate(gpriv->can_clk); 1944 - 1945 - if (gpriv->fcan == RCANFD_CANFDCLK) 1946 - /* CANFD clock is further divided by (1/2) within the IP */ 1947 - fcan_freq /= info->postdiv; 1948 1950 1949 1951 addr = devm_platform_ioremap_resource(pdev, 0); 1950 1952 if (IS_ERR(addr)) { ··· 2049 2059 } 2050 2060 2051 2061 platform_set_drvdata(pdev, gpriv); 2052 - dev_info(dev, "global operational state (clk %d, fdmode %d)\n", 2053 - gpriv->fcan, gpriv->fdmode); 2062 + dev_info(dev, "global operational state (%s clk, %s mode)\n", 2063 + gpriv->extclk ? "ext" : "canfd", 2064 + gpriv->fdmode ? "fd" : "classical"); 2054 2065 return 0; 2055 2066 2056 2067 fail_channel:
+43 -39
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
··· 2 2 // 3 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 4 // 5 - // Copyright (c) 2019, 2020, 2021 Pengutronix, 5 + // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, 6 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 7 // 8 8 // Based on: ··· 744 744 745 745 mcp251xfd_chip_interrupts_disable(priv); 746 746 mcp251xfd_chip_rx_int_disable(priv); 747 + mcp251xfd_timestamp_stop(priv); 747 748 mcp251xfd_chip_sleep(priv); 748 749 } 749 750 ··· 763 762 err = mcp251xfd_chip_timestamp_init(priv); 764 763 if (err) 765 764 goto out_chip_stop; 765 + 766 + mcp251xfd_timestamp_start(priv); 766 767 767 768 err = mcp251xfd_set_bittiming(priv); 768 769 if (err) ··· 794 791 795 792 return 0; 796 793 797 - out_chip_stop: 794 + out_chip_stop: 798 795 mcp251xfd_dump(priv); 799 796 mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED); 800 797 ··· 870 867 871 868 static struct sk_buff * 872 869 mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv, 873 - struct can_frame **cf, u32 *timestamp) 870 + struct can_frame **cf, u32 *ts_raw) 874 871 { 875 872 struct sk_buff *skb; 876 873 int err; 877 874 878 - err = mcp251xfd_get_timestamp(priv, timestamp); 875 + err = mcp251xfd_get_timestamp_raw(priv, ts_raw); 879 876 if (err) 880 877 return NULL; 881 878 882 879 skb = alloc_can_err_skb(priv->ndev, cf); 883 880 if (skb) 884 - mcp251xfd_skb_set_timestamp(priv, skb, *timestamp); 881 + mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw); 885 882 886 883 return skb; 887 884 } ··· 892 889 struct mcp251xfd_rx_ring *ring; 893 890 struct sk_buff *skb; 894 891 struct can_frame *cf; 895 - u32 timestamp, rxovif; 892 + u32 ts_raw, rxovif; 896 893 int err, i; 897 894 898 895 stats->rx_over_errors++; ··· 927 924 return err; 928 925 } 929 926 930 - skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp); 927 + skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); 931 928 if (!skb) 932 929 return 0; 933 930 934 931 cf->can_id |= CAN_ERR_CRTL; 935 932 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 936 933 937 - err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); 934 + err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); 938 935 if (err) 939 936 stats->rx_fifo_errors++; 940 937 ··· 951 948 static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) 952 949 { 953 950 struct net_device_stats *stats = &priv->ndev->stats; 954 - u32 bdiag1, timestamp; 951 + u32 bdiag1, ts_raw; 955 952 struct sk_buff *skb; 956 953 struct can_frame *cf = NULL; 957 954 int err; 958 955 959 - err = mcp251xfd_get_timestamp(priv, &timestamp); 956 + err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); 960 957 if (err) 961 958 return err; 962 959 ··· 1038 1035 if (!cf) 1039 1036 return 0; 1040 1037 1041 - mcp251xfd_skb_set_timestamp(priv, skb, timestamp); 1042 - err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); 1038 + mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw); 1039 + err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); 1043 1040 if (err) 1044 1041 stats->rx_fifo_errors++; 1045 1042 ··· 1052 1049 struct sk_buff *skb; 1053 1050 struct can_frame *cf = NULL; 1054 1051 enum can_state new_state, rx_state, tx_state; 1055 - u32 trec, timestamp; 1052 + u32 trec, ts_raw; 1056 1053 int err; 1057 1054 1058 1055 err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec); ··· 1082 1079 /* The skb allocation might fail, but can_change_state() 1083 1080 * handles cf == NULL. 1084 1081 */ 1085 - skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp); 1082 + skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); 1086 1083 can_change_state(priv->ndev, cf, tx_state, rx_state); 1087 1084 1088 1085 if (new_state == CAN_STATE_BUS_OFF) { ··· 1113 1110 cf->data[7] = bec.rxerr; 1114 1111 } 1115 1112 1116 - err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); 1113 + err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); 1117 1114 if (err) 1118 1115 stats->rx_fifo_errors++; 1119 1116 ··· 1138 1135 return 0; 1139 1136 } 1140 1137 1141 - /* According to MCP2517FD errata DS80000792B 1., during a TX 1138 + /* According to MCP2517FD errata DS80000792C 1., during a TX 1142 1139 * MAB underflow, the controller will transition to Restricted 1143 1140 * Operation Mode or Listen Only Mode (depending on SERR2LOM). 1144 1141 * ··· 1183 1180 1184 1181 /* TX MAB underflow 1185 1182 * 1186 - * According to MCP2517FD Errata DS80000792B 1. a TX MAB 1183 + * According to MCP2517FD Errata DS80000792C 1. a TX MAB 1187 1184 * underflow is indicated by SERRIF and MODIF. 1188 1185 * 1189 1186 * In addition to the effects mentioned in the Errata, there ··· 1227 1224 1228 1225 /* RX MAB overflow 1229 1226 * 1230 - * According to MCP2517FD Errata DS80000792B 1. a RX MAB 1227 + * According to MCP2517FD Errata DS80000792C 1. a RX MAB 1231 1228 * overflow is indicated by SERRIF. 1232 1229 * 1233 1230 * In addition to the effects mentioned in the Errata, (most ··· 1334 1331 return err; 1335 1332 1336 1333 /* Errata Reference: 1337 - * mcp2517fd: DS80000789B, mcp2518fd: DS80000792C 2. 1334 + * mcp2517fd: DS80000789C 3., mcp2518fd: DS80000792E 2., 1335 + * mcp251863: DS80000984A 2. 1338 1336 * 1339 1337 * ECC single error correction does not work in all cases: 1340 1338 * ··· 1580 1576 handled = IRQ_HANDLED; 1581 1577 } while (1); 1582 1578 1583 - out_fail: 1579 + out_fail: 1584 1580 can_rx_offload_threaded_irq_finish(&priv->offload); 1585 1581 1586 1582 netdev_err(priv->ndev, "IRQ handler returned %d (intf=0x%08x).\n", ··· 1614 1610 if (err) 1615 1611 goto out_mcp251xfd_ring_free; 1616 1612 1613 + mcp251xfd_timestamp_init(priv); 1614 + 1617 1615 err = mcp251xfd_chip_start(priv); 1618 1616 if (err) 1619 1617 goto out_transceiver_disable; 1620 1618 1621 - mcp251xfd_timestamp_init(priv); 1622 1619 clear_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 1623 1620 can_rx_offload_enable(&priv->offload); 1624 1621 ··· 1646 1641 1647 1642 return 0; 1648 1643 1649 - out_free_irq: 1644 + out_free_irq: 1650 1645 free_irq(spi->irq, priv); 1651 - out_destroy_workqueue: 1646 + out_destroy_workqueue: 1652 1647 destroy_workqueue(priv->wq); 1653 - out_can_rx_offload_disable: 1648 + out_can_rx_offload_disable: 1654 1649 can_rx_offload_disable(&priv->offload); 1655 1650 set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 1656 - mcp251xfd_timestamp_stop(priv); 1657 - out_transceiver_disable: 1651 + out_transceiver_disable: 1658 1652 mcp251xfd_transceiver_disable(priv); 1659 - out_mcp251xfd_ring_free: 1653 + out_mcp251xfd_ring_free: 1660 1654 mcp251xfd_ring_free(priv); 1661 - out_pm_runtime_put: 1655 + out_pm_runtime_put: 1662 1656 mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED); 1663 1657 pm_runtime_put(ndev->dev.parent); 1664 - out_close_candev: 1658 + out_close_candev: 1665 1659 close_candev(ndev); 1666 1660 1667 1661 return err; ··· 1678 1674 free_irq(ndev->irq, priv); 1679 1675 destroy_workqueue(priv->wq); 1680 1676 can_rx_offload_disable(&priv->offload); 1681 - mcp251xfd_timestamp_stop(priv); 1682 1677 mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED); 1683 1678 mcp251xfd_transceiver_disable(priv); 1684 1679 mcp251xfd_ring_free(priv); ··· 1823 1820 *effective_speed_hz_slow = xfer[0].effective_speed_hz; 1824 1821 *effective_speed_hz_fast = xfer[1].effective_speed_hz; 1825 1822 1826 - out_kfree_buf_tx: 1823 + out_kfree_buf_tx: 1827 1824 kfree(buf_tx); 1828 - out_kfree_buf_rx: 1825 + out_kfree_buf_rx: 1829 1826 kfree(buf_rx); 1830 1827 1831 1828 return err; ··· 1939 1936 1940 1937 return 0; 1941 1938 1942 - out_unregister_candev: 1939 + out_unregister_candev: 1943 1940 unregister_candev(ndev); 1944 - out_chip_sleep: 1941 + out_chip_sleep: 1945 1942 mcp251xfd_chip_sleep(priv); 1946 - out_runtime_disable: 1943 + out_runtime_disable: 1947 1944 pm_runtime_disable(ndev->dev.parent); 1948 - out_runtime_put_noidle: 1945 + out_runtime_put_noidle: 1949 1946 pm_runtime_put_noidle(ndev->dev.parent); 1950 1947 mcp251xfd_clks_and_vdd_disable(priv); 1951 1948 ··· 2098 2095 priv->devtype_data = *(struct mcp251xfd_devtype_data *)spi_get_device_match_data(spi); 2099 2096 2100 2097 /* Errata Reference: 2101 - * mcp2517fd: DS80000792C 5., mcp2518fd: DS80000789C 4. 2098 + * mcp2517fd: DS80000792C 5., mcp2518fd: DS80000789E 4., 2099 + * mcp251863: DS80000984A 4. 2102 2100 * 2103 2101 * The SPI can write corrupted data to the RAM at fast SPI 2104 2102 * speeds: ··· 2159 2155 2160 2156 return 0; 2161 2157 2162 - out_can_rx_offload_del: 2158 + out_can_rx_offload_del: 2163 2159 can_rx_offload_del(&priv->offload); 2164 - out_free_candev: 2160 + out_free_candev: 2165 2161 spi->max_speed_hz = priv->spi_max_speed_hz_orig; 2166 2162 2167 2163 free_candev(ndev);
+1 -1
drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c
··· 94 94 kfree(buf); 95 95 } 96 96 97 - out: 97 + out: 98 98 mcp251xfd_dump_header(iter, MCP251XFD_DUMP_OBJECT_TYPE_REG, reg); 99 99 } 100 100
+1 -1
drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
··· 397 397 398 398 return err; 399 399 } 400 - out: 400 + out: 401 401 memcpy(val_buf, buf_rx->data, val_len); 402 402 403 403 return 0;
+5
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
··· 206 206 int i, j; 207 207 208 208 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { 209 + rx_ring->last_valid = timecounter_read(&priv->tc); 209 210 rx_ring->head = 0; 210 211 rx_ring->tail = 0; 211 212 rx_ring->base = *base; ··· 486 485 clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); 487 486 } 488 487 488 + tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) - 489 + ilog2(tx_ring->obj_num); 489 490 tx_ring->obj_size = tx_obj_size; 490 491 491 492 rem = priv->rx_obj_num; ··· 510 507 } 511 508 512 509 rx_ring->obj_num = rx_obj_num; 510 + rx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(rx_ring->obj_num_shift_to_u8) - 511 + ilog2(rx_obj_num); 513 512 rx_ring->obj_size = rx_obj_size; 514 513 priv->rx[i] = rx_ring; 515 514 }
+111 -54
drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
··· 2 2 // 3 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 4 // 5 - // Copyright (c) 2019, 2020, 2021 Pengutronix, 5 + // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, 6 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 7 // 8 8 // Based on: ··· 16 16 17 17 #include "mcp251xfd.h" 18 18 19 - static inline int 20 - mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv, 21 - const struct mcp251xfd_rx_ring *ring, 22 - u8 *rx_head, bool *fifo_empty) 19 + static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta) 23 20 { 24 - u32 fifo_sta; 25 - int err; 21 + return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); 22 + } 26 23 27 - err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), 28 - &fifo_sta); 29 - if (err) 30 - return err; 31 - 32 - *rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); 33 - *fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); 34 - 35 - return 0; 24 + static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta) 25 + { 26 + return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; 36 27 } 37 28 38 29 static inline int ··· 71 80 } 72 81 73 82 static int 74 - mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv, 75 - struct mcp251xfd_rx_ring *ring) 83 + mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv, 84 + const struct mcp251xfd_rx_ring *ring, 85 + u8 *len_p) 76 86 { 77 - u32 new_head; 78 - u8 chip_rx_head; 79 - bool fifo_empty; 87 + const u8 shift = ring->obj_num_shift_to_u8; 88 + u8 chip_head, tail, len; 89 + u32 fifo_sta; 80 90 int err; 81 91 82 - err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head, 83 - &fifo_empty); 84 - if (err || fifo_empty) 92 + err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), 93 + &fifo_sta); 94 + if (err) 85 95 return err; 86 96 87 - /* chip_rx_head, is the next RX-Object filled by the HW. 88 - * The new RX head must be >= the old head. 97 + if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) { 98 + *len_p = 0; 99 + return 0; 100 + } 101 + 102 + if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) { 103 + *len_p = ring->obj_num; 104 + return 0; 105 + } 106 + 107 + chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); 108 + 109 + err = mcp251xfd_check_rx_tail(priv, ring); 110 + if (err) 111 + return err; 112 + tail = mcp251xfd_get_rx_tail(ring); 113 + 114 + /* First shift to full u8. The subtraction works on signed 115 + * values, that keeps the difference steady around the u8 116 + * overflow. The right shift acts on len, which is an u8. 89 117 */ 90 - new_head = round_down(ring->head, ring->obj_num) + chip_rx_head; 91 - if (new_head <= ring->head) 92 - new_head += ring->obj_num; 118 + BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head)); 119 + BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail)); 120 + BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len)); 93 121 94 - ring->head = new_head; 122 + len = (chip_head << shift) - (tail << shift); 123 + *len_p = len >> shift; 95 124 96 - return mcp251xfd_check_rx_tail(priv, ring); 125 + return 0; 97 126 } 98 127 99 128 static void ··· 159 148 160 149 if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) 161 150 memcpy(cfd->data, hw_rx_obj->data, cfd->len); 162 - 163 - mcp251xfd_skb_set_timestamp(priv, skb, hw_rx_obj->ts); 164 151 } 165 152 166 153 static int ··· 169 160 struct net_device_stats *stats = &priv->ndev->stats; 170 161 struct sk_buff *skb; 171 162 struct canfd_frame *cfd; 163 + u64 timestamp; 172 164 int err; 165 + 166 + /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI 167 + * bits of a FIFOSTA register, here the RX FIFO head index 168 + * might be corrupted and we might process past the RX FIFO's 169 + * head into old CAN frames. 170 + * 171 + * Compare the timestamp of currently processed CAN frame with 172 + * last valid frame received. Abort with -EBADMSG if an old 173 + * CAN frame is detected. 174 + */ 175 + timestamp = timecounter_cyc2time(&priv->tc, hw_rx_obj->ts); 176 + if (timestamp <= ring->last_valid) { 177 + stats->rx_fifo_errors++; 178 + 179 + return -EBADMSG; 180 + } 181 + ring->last_valid = timestamp; 173 182 174 183 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) 175 184 skb = alloc_canfd_skb(priv->ndev, &cfd); ··· 199 172 return 0; 200 173 } 201 174 175 + mcp251xfd_skb_set_timestamp(skb, timestamp); 202 176 mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb); 203 177 err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts); 204 178 if (err) ··· 226 198 } 227 199 228 200 static int 201 + mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv, 202 + struct mcp251xfd_rx_ring *ring, 203 + u8 len) 204 + { 205 + int offset; 206 + int err; 207 + 208 + if (!len) 209 + return 0; 210 + 211 + ring->head += len; 212 + 213 + /* Increment the RX FIFO tail pointer 'len' times in a 214 + * single SPI message. 215 + * 216 + * Note: 217 + * Calculate offset, so that the SPI transfer ends on 218 + * the last message of the uinc_xfer array, which has 219 + * "cs_change == 0", to properly deactivate the chip 220 + * select. 221 + */ 222 + offset = ARRAY_SIZE(ring->uinc_xfer) - len; 223 + err = spi_sync_transfer(priv->spi, 224 + ring->uinc_xfer + offset, len); 225 + if (err) 226 + return err; 227 + 228 + ring->tail += len; 229 + 230 + return 0; 231 + } 232 + 233 + static int 229 234 mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, 230 235 struct mcp251xfd_rx_ring *ring) 231 236 { 232 237 struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj; 233 - u8 rx_tail, len; 238 + u8 rx_tail, len, l; 234 239 int err, i; 235 240 236 - err = mcp251xfd_rx_ring_update(priv, ring); 241 + err = mcp251xfd_get_rx_len(priv, ring, &len); 237 242 if (err) 238 243 return err; 239 244 240 - while ((len = mcp251xfd_get_rx_linear_len(ring))) { 241 - int offset; 242 - 245 + while ((l = mcp251xfd_get_rx_linear_len(ring, len))) { 243 246 rx_tail = mcp251xfd_get_rx_tail(ring); 244 247 245 248 err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj, 246 - rx_tail, len); 249 + rx_tail, l); 247 250 if (err) 248 251 return err; 249 252 250 - for (i = 0; i < len; i++) { 253 + for (i = 0; i < l; i++) { 251 254 err = mcp251xfd_handle_rxif_one(priv, ring, 252 255 (void *)hw_rx_obj + 253 256 i * ring->obj_size); 254 - if (err) 257 + 258 + /* -EBADMSG means we're affected by mcp2518fd 259 + * erratum DS80000789E 6., i.e. the timestamp 260 + * in the RX object is older that the last 261 + * valid received CAN frame. Don't process any 262 + * further and mark processed frames as good. 263 + */ 264 + if (err == -EBADMSG) 265 + return mcp251xfd_handle_rxif_ring_uinc(priv, ring, i); 266 + else if (err) 255 267 return err; 256 268 } 257 269 258 - /* Increment the RX FIFO tail pointer 'len' times in a 259 - * single SPI message. 260 - * 261 - * Note: 262 - * Calculate offset, so that the SPI transfer ends on 263 - * the last message of the uinc_xfer array, which has 264 - * "cs_change == 0", to properly deactivate the chip 265 - * select. 266 - */ 267 - offset = ARRAY_SIZE(ring->uinc_xfer) - len; 268 - err = spi_sync_transfer(priv->spi, 269 - ring->uinc_xfer + offset, len); 270 + err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l); 270 271 if (err) 271 272 return err; 272 273 273 - ring->tail += len; 274 + len -= l; 274 275 } 275 276 276 277 return 0;
+67 -62
drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
··· 2 2 // 3 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 4 // 5 - // Copyright (c) 2019, 2020, 2021 Pengutronix, 5 + // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, 6 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 7 // 8 8 // Based on: ··· 15 15 #include <linux/bitfield.h> 16 16 17 17 #include "mcp251xfd.h" 18 + 19 + static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta) 20 + { 21 + return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); 22 + } 18 23 19 24 static inline int 20 25 mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, ··· 61 56 } 62 57 63 58 static int 64 - mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) 65 - { 66 - const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 67 - u32 tef_sta; 68 - int err; 69 - 70 - err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); 71 - if (err) 72 - return err; 73 - 74 - if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { 75 - netdev_err(priv->ndev, 76 - "Transmit Event FIFO buffer overflow.\n"); 77 - return -ENOBUFS; 78 - } 79 - 80 - netdev_info(priv->ndev, 81 - "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", 82 - tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? 83 - "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? 84 - "not empty" : "empty", 85 - seq, priv->tef->tail, priv->tef->head, tx_ring->head); 86 - 87 - /* The Sequence Number in the TEF doesn't match our tef_tail. */ 88 - return -EAGAIN; 89 - } 90 - 91 - static int 92 59 mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, 93 60 const struct mcp251xfd_hw_tef_obj *hw_tef_obj, 94 61 unsigned int *frame_len_ptr) 95 62 { 96 63 struct net_device_stats *stats = &priv->ndev->stats; 64 + u32 seq, tef_tail_masked, tef_tail; 97 65 struct sk_buff *skb; 98 - u32 seq, seq_masked, tef_tail_masked, tef_tail; 99 66 100 - seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, 67 + /* Use the MCP2517FD mask on the MCP2518FD, too. We only 68 + * compare 7 bits, this is enough to detect old TEF objects. 69 + */ 70 + seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK, 101 71 hw_tef_obj->flags); 102 - 103 - /* Use the MCP2517FD mask on the MCP2518FD, too. We only 104 - * compare 7 bits, this should be enough to detect 105 - * net-yet-completed, i.e. old TEF objects. 106 - */ 107 - seq_masked = seq & 108 - field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 109 72 tef_tail_masked = priv->tef->tail & 110 73 field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 111 - if (seq_masked != tef_tail_masked) 112 - return mcp251xfd_handle_tefif_recover(priv, seq); 74 + 75 + /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI 76 + * bits of a FIFOSTA register, here the TX FIFO tail index 77 + * might be corrupted and we might process past the TEF FIFO's 78 + * head into old CAN frames. 79 + * 80 + * Compare the sequence number of the currently processed CAN 81 + * frame with the expected sequence number. Abort with 82 + * -EBADMSG if an old CAN frame is detected. 83 + */ 84 + if (seq != tef_tail_masked) { 85 + netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__, 86 + seq, tef_tail_masked); 87 + stats->tx_fifo_errors++; 88 + 89 + return -EBADMSG; 90 + } 113 91 114 92 tef_tail = mcp251xfd_get_tef_tail(priv); 115 93 skb = priv->can.echo_skb[tef_tail]; 116 94 if (skb) 117 - mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts); 95 + mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts); 118 96 stats->tx_bytes += 119 97 can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload, 120 98 tef_tail, hw_tef_obj->ts, ··· 108 120 return 0; 109 121 } 110 122 111 - static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) 123 + static int 124 + mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) 112 125 { 113 126 const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 114 - unsigned int new_head; 115 - u8 chip_tx_tail; 127 + const u8 shift = tx_ring->obj_num_shift_to_u8; 128 + u8 chip_tx_tail, tail, len; 129 + u32 fifo_sta; 116 130 int err; 117 131 118 - err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); 132 + err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), 133 + &fifo_sta); 119 134 if (err) 120 135 return err; 121 136 122 - /* chip_tx_tail, is the next TX-Object send by the HW. 123 - * The new TEF head must be >= the old head, ... 137 + if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) { 138 + *len_p = tx_ring->obj_num; 139 + return 0; 140 + } 141 + 142 + chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); 143 + 144 + err = mcp251xfd_check_tef_tail(priv); 145 + if (err) 146 + return err; 147 + tail = mcp251xfd_get_tef_tail(priv); 148 + 149 + /* First shift to full u8. The subtraction works on signed 150 + * values, that keeps the difference steady around the u8 151 + * overflow. The right shift acts on len, which is an u8. 124 152 */ 125 - new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; 126 - if (new_head <= priv->tef->head) 127 - new_head += tx_ring->obj_num; 153 + BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail)); 154 + BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail)); 155 + BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len)); 128 156 129 - /* ... but it cannot exceed the TX head. */ 130 - priv->tef->head = min(new_head, tx_ring->head); 157 + len = (chip_tx_tail << shift) - (tail << shift); 158 + *len_p = len >> shift; 131 159 132 - return mcp251xfd_check_tef_tail(priv); 160 + return 0; 133 161 } 134 162 135 163 static inline int ··· 186 182 u8 tef_tail, len, l; 187 183 int err, i; 188 184 189 - err = mcp251xfd_tef_ring_update(priv); 185 + err = mcp251xfd_get_tef_len(priv, &len); 190 186 if (err) 191 187 return err; 192 188 193 189 tef_tail = mcp251xfd_get_tef_tail(priv); 194 - len = mcp251xfd_get_tef_len(priv); 195 - l = mcp251xfd_get_tef_linear_len(priv); 190 + l = mcp251xfd_get_tef_linear_len(priv, len); 196 191 err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); 197 192 if (err) 198 193 return err; ··· 206 203 unsigned int frame_len = 0; 207 204 208 205 err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); 209 - /* -EAGAIN means the Sequence Number in the TEF 210 - * doesn't match our tef_tail. This can happen if we 211 - * read the TEF objects too early. Leave loop let the 212 - * interrupt handler call us again. 206 + /* -EBADMSG means we're affected by mcp2518fd erratum 207 + * DS80000789E 6., i.e. the Sequence Number in the TEF 208 + * doesn't match our tef_tail. Don't process any 209 + * further and mark processed frames as good. 213 210 */ 214 - if (err == -EAGAIN) 211 + if (err == -EBADMSG) 215 212 goto out_netif_wake_queue; 216 213 if (err) 217 214 return err; ··· 219 216 total_frame_len += frame_len; 220 217 } 221 218 222 - out_netif_wake_queue: 219 + out_netif_wake_queue: 223 220 len = i; /* number of handled goods TEFs */ 224 221 if (len) { 225 222 struct mcp251xfd_tef_ring *ring = priv->tef; 226 223 struct mcp251xfd_tx_ring *tx_ring = priv->tx; 227 224 int offset; 225 + 226 + ring->head += len; 228 227 229 228 /* Increment the TEF FIFO tail pointer 'len' times in 230 229 * a single SPI message.
+11 -18
drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
··· 2 2 // 3 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 4 // 5 - // Copyright (c) 2021 Pengutronix, 5 + // Copyright (c) 2021, 2023 Pengutronix, 6 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 7 // 8 8 ··· 11 11 12 12 #include "mcp251xfd.h" 13 13 14 - static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc) 14 + static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc) 15 15 { 16 16 const struct mcp251xfd_priv *priv; 17 - u32 timestamp = 0; 17 + u32 ts_raw = 0; 18 18 int err; 19 19 20 20 priv = container_of(cc, struct mcp251xfd_priv, cc); 21 - err = mcp251xfd_get_timestamp(priv, &timestamp); 21 + err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); 22 22 if (err) 23 23 netdev_err(priv->ndev, 24 24 "Error %d while reading timestamp. HW timestamps may be inaccurate.", 25 25 err); 26 26 27 - return timestamp; 27 + return ts_raw; 28 28 } 29 29 30 30 static void mcp251xfd_timestamp_work(struct work_struct *work) ··· 39 39 MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); 40 40 } 41 41 42 - void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, 43 - struct sk_buff *skb, u32 timestamp) 44 - { 45 - struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); 46 - u64 ns; 47 - 48 - ns = timecounter_cyc2time(&priv->tc, timestamp); 49 - hwtstamps->hwtstamp = ns_to_ktime(ns); 50 - } 51 - 52 42 void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv) 53 43 { 54 44 struct cyclecounter *cc = &priv->cc; 55 45 56 - cc->read = mcp251xfd_timestamp_read; 46 + cc->read = mcp251xfd_timestamp_raw_read; 57 47 cc->mask = CYCLECOUNTER_MASK(32); 58 48 cc->shift = 1; 59 49 cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift); 60 50 61 - timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns()); 62 - 63 51 INIT_DELAYED_WORK(&priv->timestamp, mcp251xfd_timestamp_work); 52 + } 53 + 54 + void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv) 55 + { 56 + timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns()); 64 57 schedule_delayed_work(&priv->timestamp, 65 58 MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); 66 59 }
+30 -26
drivers/net/can/spi/mcp251xfd/mcp251xfd.h
··· 2 2 * 3 3 * mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 4 * 5 - * Copyright (c) 2019, 2020, 2021 Pengutronix, 5 + * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, 6 6 * Marc Kleine-Budde <kernel@pengutronix.de> 7 7 * Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> 8 8 */ ··· 524 524 525 525 /* u8 obj_num equals tx_ring->obj_num */ 526 526 /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ 527 + /* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */ 527 528 528 529 union mcp251xfd_write_reg_buf irq_enable_buf; 529 530 struct spi_transfer irq_enable_xfer; ··· 543 542 u8 nr; 544 543 u8 fifo_nr; 545 544 u8 obj_num; 545 + u8 obj_num_shift_to_u8; 546 546 u8 obj_size; 547 547 548 548 struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; ··· 554 552 unsigned int head; 555 553 unsigned int tail; 556 554 555 + /* timestamp of the last valid received CAN frame */ 556 + u64 last_valid; 557 + 557 558 u16 base; 558 559 u8 nr; 559 560 u8 fifo_nr; 560 561 u8 obj_num; 562 + u8 obj_num_shift_to_u8; 561 563 u8 obj_size; 562 564 563 565 union mcp251xfd_write_reg_buf irq_enable_buf; ··· 815 809 return data; 816 810 } 817 811 818 - static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv, 819 - u32 *timestamp) 812 + static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv, 813 + u32 *ts_raw) 820 814 { 821 - return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp); 815 + return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw); 816 + } 817 + 818 + static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns) 819 + { 820 + struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); 821 + 822 + hwtstamps->hwtstamp = ns_to_ktime(ns); 823 + } 824 + 825 + static inline 826 + void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv, 827 + struct sk_buff *skb, u32 ts_raw) 828 + { 829 + u64 ns; 830 + 831 + ns = timecounter_cyc2time(&priv->tc, ts_raw); 832 + mcp251xfd_skb_set_timestamp(skb, ns); 822 833 } 823 834 824 835 static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) ··· 884 861 return priv->tef->tail & (priv->tx->obj_num - 1); 885 862 } 886 863 887 - static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) 864 + static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len) 888 865 { 889 - return priv->tef->head - priv->tef->tail; 890 - } 891 - 892 - static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv) 893 - { 894 - u8 len; 895 - 896 - len = mcp251xfd_get_tef_len(priv); 897 - 898 866 return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); 899 867 } 900 868 ··· 928 914 return ring->tail & (ring->obj_num - 1); 929 915 } 930 916 931 - static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring) 932 - { 933 - return ring->head - ring->tail; 934 - } 935 - 936 917 static inline u8 937 - mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring) 918 + mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len) 938 919 { 939 - u8 len; 940 - 941 - len = mcp251xfd_get_rx_len(ring); 942 - 943 920 return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring)); 944 921 } 945 922 ··· 956 951 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); 957 952 int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); 958 953 int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); 959 - void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, 960 - struct sk_buff *skb, u32 timestamp); 961 954 void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); 955 + void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv); 962 956 void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); 963 957 964 958 void mcp251xfd_tx_obj_write_sync(struct work_struct *work);
+5
drivers/net/can/usb/gs_usb.c
··· 40 40 #define USB_ABE_CANDEBUGGER_FD_VENDOR_ID 0x16d0 41 41 #define USB_ABE_CANDEBUGGER_FD_PRODUCT_ID 0x10b8 42 42 43 + #define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0 44 + #define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30 45 + 43 46 #define GS_USB_ENDPOINT_IN 1 44 47 #define GS_USB_ENDPOINT_OUT 2 45 48 ··· 1533 1530 USB_CES_CANEXT_FD_PRODUCT_ID, 0) }, 1534 1531 { USB_DEVICE_INTERFACE_NUMBER(USB_ABE_CANDEBUGGER_FD_VENDOR_ID, 1535 1532 USB_ABE_CANDEBUGGER_FD_PRODUCT_ID, 0) }, 1533 + { USB_DEVICE_INTERFACE_NUMBER(USB_XYLANTA_SAINT3_VENDOR_ID, 1534 + USB_XYLANTA_SAINT3_PRODUCT_ID, 0) }, 1536 1535 {} /* Terminating entry */ 1537 1536 }; 1538 1537