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-5.18-20220313' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

linux-can-next-for-5.18-20220313

Marc Kleine-Budde says:

====================
pull-request: can-next 2022-03-13

this is a pull request of 13 patches for net-next/master.

The 1st patch is by me and fixes the freeing of a skb in the vxcan
driver (initially added in this net-next window).

The remaining 12 patches are also by me and target the mcp251xfd
driver. The first patch fixes a printf modifier (initially added in
this net-next window). The remaining patches add ethtool based ring
and RX/TX IRQ coalescing support to the driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+649 -63
+2
drivers/net/can/spi/mcp251xfd/Makefile
··· 6 6 mcp251xfd-objs += mcp251xfd-chip-fifo.o 7 7 mcp251xfd-objs += mcp251xfd-core.o 8 8 mcp251xfd-objs += mcp251xfd-crc16.o 9 + mcp251xfd-objs += mcp251xfd-ethtool.o 10 + mcp251xfd-objs += mcp251xfd-ram.o 9 11 mcp251xfd-objs += mcp251xfd-regmap.o 10 12 mcp251xfd-objs += mcp251xfd-ring.o 11 13 mcp251xfd-objs += mcp251xfd-rx.o
+7
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
··· 1598 1598 goto out_transceiver_disable; 1599 1599 1600 1600 mcp251xfd_timestamp_init(priv); 1601 + clear_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 1601 1602 can_rx_offload_enable(&priv->offload); 1602 1603 1603 1604 err = request_threaded_irq(spi->irq, NULL, mcp251xfd_irq, ··· 1619 1618 free_irq(spi->irq, priv); 1620 1619 out_can_rx_offload_disable: 1621 1620 can_rx_offload_disable(&priv->offload); 1621 + set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 1622 1622 mcp251xfd_timestamp_stop(priv); 1623 1623 out_transceiver_disable: 1624 1624 mcp251xfd_transceiver_disable(priv); ··· 1639 1637 struct mcp251xfd_priv *priv = netdev_priv(ndev); 1640 1638 1641 1639 netif_stop_queue(ndev); 1640 + set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 1641 + hrtimer_cancel(&priv->rx_irq_timer); 1642 1642 mcp251xfd_chip_interrupts_disable(priv); 1643 1643 free_irq(ndev->irq, priv); 1644 1644 can_rx_offload_disable(&priv->offload); ··· 1875 1871 if (err) 1876 1872 goto out_chip_sleep; 1877 1873 1874 + mcp251xfd_ethtool_init(priv); 1875 + 1878 1876 err = register_candev(ndev); 1879 1877 if (err) 1880 1878 goto out_chip_sleep; ··· 2040 2034 CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | 2041 2035 CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO | 2042 2036 CAN_CTRLMODE_CC_LEN8_DLC; 2037 + set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); 2043 2038 priv->ndev = ndev; 2044 2039 priv->spi = spi; 2045 2040 priv->rx_int = rx_int;
+143
drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 + // 5 + // Copyright (c) 2021, 2022 Pengutronix, 6 + // Marc Kleine-Budde <kernel@pengutronix.de> 7 + // 8 + 9 + #include <linux/ethtool.h> 10 + 11 + #include "mcp251xfd.h" 12 + #include "mcp251xfd-ram.h" 13 + 14 + static void 15 + mcp251xfd_ring_get_ringparam(struct net_device *ndev, 16 + struct ethtool_ringparam *ring, 17 + struct kernel_ethtool_ringparam *kernel_ring, 18 + struct netlink_ext_ack *extack) 19 + { 20 + const struct mcp251xfd_priv *priv = netdev_priv(ndev); 21 + const bool fd_mode = mcp251xfd_is_fd_mode(priv); 22 + struct can_ram_layout layout; 23 + 24 + can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode); 25 + ring->rx_max_pending = layout.max_rx; 26 + ring->tx_max_pending = layout.max_tx; 27 + 28 + ring->rx_pending = priv->rx_obj_num; 29 + ring->tx_pending = priv->tx->obj_num; 30 + } 31 + 32 + static int 33 + mcp251xfd_ring_set_ringparam(struct net_device *ndev, 34 + struct ethtool_ringparam *ring, 35 + struct kernel_ethtool_ringparam *kernel_ring, 36 + struct netlink_ext_ack *extack) 37 + { 38 + struct mcp251xfd_priv *priv = netdev_priv(ndev); 39 + const bool fd_mode = mcp251xfd_is_fd_mode(priv); 40 + struct can_ram_layout layout; 41 + 42 + can_ram_get_layout(&layout, &mcp251xfd_ram_config, ring, NULL, fd_mode); 43 + if ((layout.cur_rx != priv->rx_obj_num || 44 + layout.cur_tx != priv->tx->obj_num) && 45 + netif_running(ndev)) 46 + return -EBUSY; 47 + 48 + priv->rx_obj_num = layout.cur_rx; 49 + priv->rx_obj_num_coalesce_irq = layout.rx_coalesce; 50 + priv->tx->obj_num = layout.cur_tx; 51 + 52 + return 0; 53 + } 54 + 55 + static int mcp251xfd_ring_get_coalesce(struct net_device *ndev, 56 + struct ethtool_coalesce *ec, 57 + struct kernel_ethtool_coalesce *kec, 58 + struct netlink_ext_ack *ext_ack) 59 + { 60 + struct mcp251xfd_priv *priv = netdev_priv(ndev); 61 + u32 rx_max_frames, tx_max_frames; 62 + 63 + /* The ethtool doc says: 64 + * To disable coalescing, set usecs = 0 and max_frames = 1. 65 + */ 66 + if (priv->rx_obj_num_coalesce_irq == 0) 67 + rx_max_frames = 1; 68 + else 69 + rx_max_frames = priv->rx_obj_num_coalesce_irq; 70 + 71 + ec->rx_max_coalesced_frames_irq = rx_max_frames; 72 + ec->rx_coalesce_usecs_irq = priv->rx_coalesce_usecs_irq; 73 + 74 + if (priv->tx_obj_num_coalesce_irq == 0) 75 + tx_max_frames = 1; 76 + else 77 + tx_max_frames = priv->tx_obj_num_coalesce_irq; 78 + 79 + ec->tx_max_coalesced_frames_irq = tx_max_frames; 80 + ec->tx_coalesce_usecs_irq = priv->tx_coalesce_usecs_irq; 81 + 82 + return 0; 83 + } 84 + 85 + static int mcp251xfd_ring_set_coalesce(struct net_device *ndev, 86 + struct ethtool_coalesce *ec, 87 + struct kernel_ethtool_coalesce *kec, 88 + struct netlink_ext_ack *ext_ack) 89 + { 90 + struct mcp251xfd_priv *priv = netdev_priv(ndev); 91 + const bool fd_mode = mcp251xfd_is_fd_mode(priv); 92 + const struct ethtool_ringparam ring = { 93 + .rx_pending = priv->rx_obj_num, 94 + .tx_pending = priv->tx->obj_num, 95 + }; 96 + struct can_ram_layout layout; 97 + 98 + can_ram_get_layout(&layout, &mcp251xfd_ram_config, &ring, ec, fd_mode); 99 + 100 + if ((layout.rx_coalesce != priv->rx_obj_num_coalesce_irq || 101 + ec->rx_coalesce_usecs_irq != priv->rx_coalesce_usecs_irq || 102 + layout.tx_coalesce != priv->tx_obj_num_coalesce_irq || 103 + ec->tx_coalesce_usecs_irq != priv->tx_coalesce_usecs_irq) && 104 + netif_running(ndev)) 105 + return -EBUSY; 106 + 107 + priv->rx_obj_num = layout.cur_rx; 108 + priv->rx_obj_num_coalesce_irq = layout.rx_coalesce; 109 + priv->rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; 110 + 111 + priv->tx->obj_num = layout.cur_tx; 112 + priv->tx_obj_num_coalesce_irq = layout.tx_coalesce; 113 + priv->tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; 114 + 115 + return 0; 116 + } 117 + 118 + static const struct ethtool_ops mcp251xfd_ethtool_ops = { 119 + .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ | 120 + ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ | 121 + ETHTOOL_COALESCE_TX_USECS_IRQ | 122 + ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, 123 + .get_ringparam = mcp251xfd_ring_get_ringparam, 124 + .set_ringparam = mcp251xfd_ring_set_ringparam, 125 + .get_coalesce = mcp251xfd_ring_get_coalesce, 126 + .set_coalesce = mcp251xfd_ring_set_coalesce, 127 + }; 128 + 129 + void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv) 130 + { 131 + struct can_ram_layout layout; 132 + 133 + priv->ndev->ethtool_ops = &mcp251xfd_ethtool_ops; 134 + 135 + can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, false); 136 + priv->rx_obj_num = layout.default_rx; 137 + priv->tx->obj_num = layout.default_tx; 138 + 139 + priv->rx_obj_num_coalesce_irq = 0; 140 + priv->tx_obj_num_coalesce_irq = 0; 141 + priv->rx_coalesce_usecs_irq = 0; 142 + priv->tx_coalesce_usecs_irq = 0; 143 + }
+153
drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 + // 5 + // Copyright (c) 2021, 2022 Pengutronix, 6 + // Marc Kleine-Budde <kernel@pengutronix.de> 7 + // 8 + 9 + #include "mcp251xfd-ram.h" 10 + 11 + static inline u8 can_ram_clamp(const struct can_ram_config *config, 12 + const struct can_ram_obj_config *obj, 13 + u8 val) 14 + { 15 + u8 max; 16 + 17 + max = min_t(u8, obj->max, obj->fifo_num * config->fifo_depth); 18 + return clamp(val, obj->min, max); 19 + } 20 + 21 + static u8 22 + can_ram_rounddown_pow_of_two(const struct can_ram_config *config, 23 + const struct can_ram_obj_config *obj, 24 + const u8 coalesce, u8 val) 25 + { 26 + u8 fifo_num = obj->fifo_num; 27 + u8 ret = 0, i; 28 + 29 + val = can_ram_clamp(config, obj, val); 30 + 31 + if (coalesce) { 32 + /* Use 1st FIFO for coalescing, if requested. 33 + * 34 + * Either use complete FIFO (and FIFO Full IRQ) for 35 + * coalescing or only half of FIFO (FIFO Half Full 36 + * IRQ) and use remaining half for normal objects. 37 + */ 38 + ret = min_t(u8, coalesce * 2, config->fifo_depth); 39 + val -= ret; 40 + fifo_num--; 41 + } 42 + 43 + for (i = 0; i < fifo_num && val; i++) { 44 + u8 n; 45 + 46 + n = min_t(u8, rounddown_pow_of_two(val), 47 + config->fifo_depth); 48 + 49 + /* skip small FIFOs */ 50 + if (n < obj->fifo_depth_min) 51 + return ret; 52 + 53 + ret += n; 54 + val -= n; 55 + } 56 + 57 + return ret; 58 + } 59 + 60 + void can_ram_get_layout(struct can_ram_layout *layout, 61 + const struct can_ram_config *config, 62 + const struct ethtool_ringparam *ring, 63 + const struct ethtool_coalesce *ec, 64 + const bool fd_mode) 65 + { 66 + u8 num_rx, num_tx; 67 + u16 ram_free; 68 + 69 + /* default CAN */ 70 + 71 + num_tx = config->tx.def[fd_mode]; 72 + num_tx = can_ram_rounddown_pow_of_two(config, &config->tx, 0, num_tx); 73 + 74 + ram_free = config->size; 75 + ram_free -= config->tx.size[fd_mode] * num_tx; 76 + 77 + num_rx = ram_free / config->rx.size[fd_mode]; 78 + 79 + layout->default_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, num_rx); 80 + layout->default_tx = num_tx; 81 + 82 + /* MAX CAN */ 83 + 84 + ram_free = config->size; 85 + ram_free -= config->tx.size[fd_mode] * config->tx.min; 86 + num_rx = ram_free / config->rx.size[fd_mode]; 87 + 88 + ram_free = config->size; 89 + ram_free -= config->rx.size[fd_mode] * config->rx.min; 90 + num_tx = ram_free / config->tx.size[fd_mode]; 91 + 92 + layout->max_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, num_rx); 93 + layout->max_tx = can_ram_rounddown_pow_of_two(config, &config->tx, 0, num_tx); 94 + 95 + /* cur CAN */ 96 + 97 + if (ring) { 98 + u8 num_rx_coalesce = 0, num_tx_coalesce = 0; 99 + 100 + num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, ring->rx_pending); 101 + 102 + /* The ethtool doc says: 103 + * To disable coalescing, set usecs = 0 and max_frames = 1. 104 + */ 105 + if (ec && !(ec->rx_coalesce_usecs_irq == 0 && 106 + ec->rx_max_coalesced_frames_irq == 1)) { 107 + u8 max; 108 + 109 + /* use only max half of available objects for coalescing */ 110 + max = min_t(u8, num_rx / 2, config->fifo_depth); 111 + num_rx_coalesce = clamp(ec->rx_max_coalesced_frames_irq, 112 + (u32)config->rx.fifo_depth_coalesce_min, 113 + (u32)max); 114 + num_rx_coalesce = rounddown_pow_of_two(num_rx_coalesce); 115 + 116 + num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 117 + num_rx_coalesce, num_rx); 118 + } 119 + 120 + ram_free = config->size - config->rx.size[fd_mode] * num_rx; 121 + num_tx = ram_free / config->tx.size[fd_mode]; 122 + num_tx = min_t(u8, ring->tx_pending, num_tx); 123 + num_tx = can_ram_rounddown_pow_of_two(config, &config->tx, 0, num_tx); 124 + 125 + /* The ethtool doc says: 126 + * To disable coalescing, set usecs = 0 and max_frames = 1. 127 + */ 128 + if (ec && !(ec->tx_coalesce_usecs_irq == 0 && 129 + ec->tx_max_coalesced_frames_irq == 1)) { 130 + u8 max; 131 + 132 + /* use only max half of available objects for coalescing */ 133 + max = min_t(u8, num_tx / 2, config->fifo_depth); 134 + num_tx_coalesce = clamp(ec->tx_max_coalesced_frames_irq, 135 + (u32)config->tx.fifo_depth_coalesce_min, 136 + (u32)max); 137 + num_tx_coalesce = rounddown_pow_of_two(num_tx_coalesce); 138 + 139 + num_tx = can_ram_rounddown_pow_of_two(config, &config->tx, 140 + num_tx_coalesce, num_tx); 141 + } 142 + 143 + layout->cur_rx = num_rx; 144 + layout->cur_tx = num_tx; 145 + layout->rx_coalesce = num_rx_coalesce; 146 + layout->tx_coalesce = num_tx_coalesce; 147 + } else { 148 + layout->cur_rx = layout->default_rx; 149 + layout->cur_tx = layout->default_tx; 150 + layout->rx_coalesce = 0; 151 + layout->tx_coalesce = 0; 152 + } 153 + }
+62
drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 + * 5 + * Copyright (c) 2021, 2022 Pengutronix, 6 + * Marc Kleine-Budde <kernel@pengutronix.de> 7 + */ 8 + 9 + #ifndef _MCP251XFD_RAM_H 10 + #define _MCP251XFD_RAM_H 11 + 12 + #include <linux/ethtool.h> 13 + 14 + #define CAN_RAM_NUM_MAX (-1) 15 + 16 + enum can_ram_mode { 17 + CAN_RAM_MODE_CAN, 18 + CAN_RAM_MODE_CANFD, 19 + __CAN_RAM_MODE_MAX 20 + }; 21 + 22 + struct can_ram_obj_config { 23 + u8 size[__CAN_RAM_MODE_MAX]; 24 + 25 + u8 def[__CAN_RAM_MODE_MAX]; 26 + u8 min; 27 + u8 max; 28 + 29 + u8 fifo_num; 30 + u8 fifo_depth_min; 31 + u8 fifo_depth_coalesce_min; 32 + }; 33 + 34 + struct can_ram_config { 35 + const struct can_ram_obj_config rx; 36 + const struct can_ram_obj_config tx; 37 + 38 + u16 size; 39 + u8 fifo_depth; 40 + }; 41 + 42 + struct can_ram_layout { 43 + u8 default_rx; 44 + u8 default_tx; 45 + 46 + u8 max_rx; 47 + u8 max_tx; 48 + 49 + u8 cur_rx; 50 + u8 cur_tx; 51 + 52 + u8 rx_coalesce; 53 + u8 tx_coalesce; 54 + }; 55 + 56 + void can_ram_get_layout(struct can_ram_layout *layout, 57 + const struct can_ram_config *config, 58 + const struct ethtool_ringparam *ring, 59 + const struct ethtool_coalesce *ec, 60 + const bool fd_mode); 61 + 62 + #endif
+214 -40
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
··· 15 15 #include <asm/unaligned.h> 16 16 17 17 #include "mcp251xfd.h" 18 + #include "mcp251xfd-ram.h" 18 19 19 20 static inline u8 20 21 mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv, ··· 71 70 /* TEF- and TX-FIFO have same number of objects */ 72 71 *base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num); 73 72 73 + /* FIFO IRQ enable */ 74 + addr = MCP251XFD_REG_TEFCON; 75 + val = MCP251XFD_REG_TEFCON_TEFOVIE | MCP251XFD_REG_TEFCON_TEFNEIE; 76 + 77 + len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->irq_enable_buf, 78 + addr, val, val); 79 + tef_ring->irq_enable_xfer.tx_buf = &tef_ring->irq_enable_buf; 80 + tef_ring->irq_enable_xfer.len = len; 81 + spi_message_init_with_transfers(&tef_ring->irq_enable_msg, 82 + &tef_ring->irq_enable_xfer, 1); 83 + 74 84 /* FIFO increment TEF tail pointer */ 75 85 addr = MCP251XFD_REG_TEFCON; 76 86 val = MCP251XFD_REG_TEFCON_UINC; ··· 105 93 * message. 106 94 */ 107 95 xfer->cs_change = 0; 96 + 97 + if (priv->tx_coalesce_usecs_irq || priv->tx_obj_num_coalesce_irq) { 98 + val = MCP251XFD_REG_TEFCON_UINC | 99 + MCP251XFD_REG_TEFCON_TEFOVIE | 100 + MCP251XFD_REG_TEFCON_TEFHIE; 101 + 102 + len = mcp251xfd_cmd_prepare_write_reg(priv, 103 + &tef_ring->uinc_irq_disable_buf, 104 + addr, val, val); 105 + xfer->tx_buf = &tef_ring->uinc_irq_disable_buf; 106 + xfer->len = len; 107 + } 108 108 } 109 109 110 110 static void ··· 205 181 *base = mcp251xfd_get_rx_obj_addr(rx_ring, rx_ring->obj_num); 206 182 *fifo_nr += 1; 207 183 208 - /* FIFO increment RX tail pointer */ 184 + /* FIFO IRQ enable */ 209 185 addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr); 186 + val = MCP251XFD_REG_FIFOCON_RXOVIE | 187 + MCP251XFD_REG_FIFOCON_TFNRFNIE; 188 + len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->irq_enable_buf, 189 + addr, val, val); 190 + rx_ring->irq_enable_xfer.tx_buf = &rx_ring->irq_enable_buf; 191 + rx_ring->irq_enable_xfer.len = len; 192 + spi_message_init_with_transfers(&rx_ring->irq_enable_msg, 193 + &rx_ring->irq_enable_xfer, 1); 194 + 195 + /* FIFO increment RX tail pointer */ 210 196 val = MCP251XFD_REG_FIFOCON_UINC; 211 197 len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf, 212 198 addr, val, val); ··· 238 204 * the chip select at the end of the message. 239 205 */ 240 206 xfer->cs_change = 0; 207 + 208 + /* Use 1st RX-FIFO for IRQ coalescing. If enabled 209 + * (rx_coalesce_usecs_irq or rx_max_coalesce_frames_irq 210 + * is activated), use the last transfer to disable: 211 + * 212 + * - TFNRFNIE (Receive FIFO Not Empty Interrupt) 213 + * 214 + * and enable: 215 + * 216 + * - TFHRFHIE (Receive FIFO Half Full Interrupt) 217 + * - or - 218 + * - TFERFFIE (Receive FIFO Full Interrupt) 219 + * 220 + * depending on rx_max_coalesce_frames_irq. 221 + * 222 + * The RXOVIE (Overflow Interrupt) is always enabled. 223 + */ 224 + if (rx_ring->nr == 0 && (priv->rx_coalesce_usecs_irq || 225 + priv->rx_obj_num_coalesce_irq)) { 226 + val = MCP251XFD_REG_FIFOCON_UINC | 227 + MCP251XFD_REG_FIFOCON_RXOVIE; 228 + 229 + if (priv->rx_obj_num_coalesce_irq == rx_ring->obj_num) 230 + val |= MCP251XFD_REG_FIFOCON_TFERFFIE; 231 + else if (priv->rx_obj_num_coalesce_irq) 232 + val |= MCP251XFD_REG_FIFOCON_TFHRFHIE; 233 + 234 + len = mcp251xfd_cmd_prepare_write_reg(priv, 235 + &rx_ring->uinc_irq_disable_buf, 236 + addr, val, val); 237 + xfer->tx_buf = &rx_ring->uinc_irq_disable_buf; 238 + xfer->len = len; 239 + } 241 240 } 242 241 } 243 242 ··· 305 238 */ 306 239 priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr); 307 240 308 - netdev_dbg(priv->ndev, 309 - "FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes\n", 310 - mcp251xfd_get_tef_obj_addr(0), 311 - priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj), 312 - priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj)); 241 + if (priv->tx_obj_num_coalesce_irq) { 242 + netdev_dbg(priv->ndev, 243 + "FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes (coalesce)\n", 244 + mcp251xfd_get_tef_obj_addr(0), 245 + priv->tx_obj_num_coalesce_irq, 246 + sizeof(struct mcp251xfd_hw_tef_obj), 247 + priv->tx_obj_num_coalesce_irq * 248 + sizeof(struct mcp251xfd_hw_tef_obj)); 249 + 250 + netdev_dbg(priv->ndev, 251 + " 0x%03x: %2d*%zu bytes = %4zu bytes\n", 252 + mcp251xfd_get_tef_obj_addr(priv->tx_obj_num_coalesce_irq), 253 + priv->tx->obj_num - priv->tx_obj_num_coalesce_irq, 254 + sizeof(struct mcp251xfd_hw_tef_obj), 255 + (priv->tx->obj_num - priv->tx_obj_num_coalesce_irq) * 256 + sizeof(struct mcp251xfd_hw_tef_obj)); 257 + } else { 258 + netdev_dbg(priv->ndev, 259 + "FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes\n", 260 + mcp251xfd_get_tef_obj_addr(0), 261 + priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj), 262 + priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj)); 263 + } 313 264 314 265 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { 315 - netdev_dbg(priv->ndev, 316 - "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n", 317 - rx_ring->nr, rx_ring->fifo_nr, 318 - mcp251xfd_get_rx_obj_addr(rx_ring, 0), 319 - rx_ring->obj_num, rx_ring->obj_size, 320 - rx_ring->obj_num * rx_ring->obj_size); 266 + if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) { 267 + netdev_dbg(priv->ndev, 268 + "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes (coalesce)\n", 269 + rx_ring->nr, rx_ring->fifo_nr, 270 + mcp251xfd_get_rx_obj_addr(rx_ring, 0), 271 + priv->rx_obj_num_coalesce_irq, rx_ring->obj_size, 272 + priv->rx_obj_num_coalesce_irq * rx_ring->obj_size); 273 + 274 + if (priv->rx_obj_num_coalesce_irq == MCP251XFD_FIFO_DEPTH) 275 + continue; 276 + 277 + netdev_dbg(priv->ndev, 278 + " 0x%03x: %2u*%u bytes = %4u bytes\n", 279 + mcp251xfd_get_rx_obj_addr(rx_ring, 280 + priv->rx_obj_num_coalesce_irq), 281 + rx_ring->obj_num - priv->rx_obj_num_coalesce_irq, 282 + rx_ring->obj_size, 283 + (rx_ring->obj_num - priv->rx_obj_num_coalesce_irq) * 284 + rx_ring->obj_size); 285 + } else { 286 + netdev_dbg(priv->ndev, 287 + "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n", 288 + rx_ring->nr, rx_ring->fifo_nr, 289 + mcp251xfd_get_rx_obj_addr(rx_ring, 0), 290 + rx_ring->obj_num, rx_ring->obj_size, 291 + rx_ring->obj_num * rx_ring->obj_size); 292 + } 321 293 } 322 294 323 295 netdev_dbg(priv->ndev, ··· 367 261 priv->tx->obj_num * priv->tx->obj_size); 368 262 369 263 netdev_dbg(priv->ndev, 370 - "FIFO setup: free: %4u bytes\n", 264 + "FIFO setup: free: %4d bytes\n", 371 265 MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START)); 372 266 373 267 ram_used = base - MCP251XFD_RAM_START; ··· 391 285 } 392 286 } 393 287 288 + static enum hrtimer_restart mcp251xfd_rx_irq_timer(struct hrtimer *t) 289 + { 290 + struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv, 291 + rx_irq_timer); 292 + struct mcp251xfd_rx_ring *ring = priv->rx[0]; 293 + 294 + if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags)) 295 + return HRTIMER_NORESTART; 296 + 297 + spi_async(priv->spi, &ring->irq_enable_msg); 298 + 299 + return HRTIMER_NORESTART; 300 + } 301 + 302 + static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t) 303 + { 304 + struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv, 305 + tx_irq_timer); 306 + struct mcp251xfd_tef_ring *ring = priv->tef; 307 + 308 + if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags)) 309 + return HRTIMER_NORESTART; 310 + 311 + spi_async(priv->spi, &ring->irq_enable_msg); 312 + 313 + return HRTIMER_NORESTART; 314 + } 315 + 316 + const struct can_ram_config mcp251xfd_ram_config = { 317 + .rx = { 318 + .size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_rx_obj_can), 319 + .size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_rx_obj_canfd), 320 + .min = MCP251XFD_RX_OBJ_NUM_MIN, 321 + .max = MCP251XFD_RX_OBJ_NUM_MAX, 322 + .def[CAN_RAM_MODE_CAN] = CAN_RAM_NUM_MAX, 323 + .def[CAN_RAM_MODE_CANFD] = CAN_RAM_NUM_MAX, 324 + .fifo_num = MCP251XFD_FIFO_RX_NUM, 325 + .fifo_depth_min = MCP251XFD_RX_FIFO_DEPTH_MIN, 326 + .fifo_depth_coalesce_min = MCP251XFD_RX_FIFO_DEPTH_COALESCE_MIN, 327 + }, 328 + .tx = { 329 + .size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_tef_obj) + 330 + sizeof(struct mcp251xfd_hw_tx_obj_can), 331 + .size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_tef_obj) + 332 + sizeof(struct mcp251xfd_hw_tx_obj_canfd), 333 + .min = MCP251XFD_TX_OBJ_NUM_MIN, 334 + .max = MCP251XFD_TX_OBJ_NUM_MAX, 335 + .def[CAN_RAM_MODE_CAN] = MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT, 336 + .def[CAN_RAM_MODE_CANFD] = MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT, 337 + .fifo_num = MCP251XFD_FIFO_TX_NUM, 338 + .fifo_depth_min = MCP251XFD_TX_FIFO_DEPTH_MIN, 339 + .fifo_depth_coalesce_min = MCP251XFD_TX_FIFO_DEPTH_COALESCE_MIN, 340 + }, 341 + .size = MCP251XFD_RAM_SIZE, 342 + .fifo_depth = MCP251XFD_FIFO_DEPTH, 343 + }; 344 + 394 345 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) 395 346 { 396 - struct mcp251xfd_tx_ring *tx_ring; 347 + const bool fd_mode = mcp251xfd_is_fd_mode(priv); 348 + struct mcp251xfd_tx_ring *tx_ring = priv->tx; 397 349 struct mcp251xfd_rx_ring *rx_ring; 398 - int tef_obj_size, tx_obj_size, rx_obj_size; 399 - int tx_obj_num; 400 - int ram_free, i; 350 + u8 tx_obj_size, rx_obj_size; 351 + u8 rem, i; 401 352 402 - tef_obj_size = sizeof(struct mcp251xfd_hw_tef_obj); 403 - if (mcp251xfd_is_fd_mode(priv)) { 404 - tx_obj_num = MCP251XFD_TX_OBJ_NUM_CANFD; 405 - tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd); 406 - rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd); 407 - } else { 408 - tx_obj_num = MCP251XFD_TX_OBJ_NUM_CAN; 409 - tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can); 410 - rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can); 353 + /* switching from CAN-2.0 to CAN-FD mode or vice versa */ 354 + if (fd_mode != test_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags)) { 355 + struct can_ram_layout layout; 356 + 357 + can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode); 358 + priv->rx_obj_num = layout.default_rx; 359 + tx_ring->obj_num = layout.default_tx; 411 360 } 412 361 413 - tx_ring = priv->tx; 414 - tx_ring->obj_num = tx_obj_num; 362 + if (fd_mode) { 363 + tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd); 364 + rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd); 365 + set_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); 366 + } else { 367 + tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can); 368 + rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can); 369 + clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); 370 + } 371 + 415 372 tx_ring->obj_size = tx_obj_size; 416 373 417 - ram_free = MCP251XFD_RAM_SIZE - tx_obj_num * 418 - (tef_obj_size + tx_obj_size); 374 + rem = priv->rx_obj_num; 375 + for (i = 0; i < ARRAY_SIZE(priv->rx) && rem; i++) { 376 + u8 rx_obj_num; 419 377 420 - for (i = 0; 421 - i < ARRAY_SIZE(priv->rx) && ram_free >= rx_obj_size; 422 - i++) { 423 - int rx_obj_num; 424 - 425 - rx_obj_num = ram_free / rx_obj_size; 426 - rx_obj_num = min(1 << (fls(rx_obj_num) - 1), 427 - MCP251XFD_RX_OBJ_NUM_MAX); 378 + if (i == 0 && priv->rx_obj_num_coalesce_irq) 379 + rx_obj_num = min_t(u8, priv->rx_obj_num_coalesce_irq * 2, 380 + MCP251XFD_FIFO_DEPTH); 381 + else 382 + rx_obj_num = min_t(u8, rounddown_pow_of_two(rem), 383 + MCP251XFD_FIFO_DEPTH); 384 + rem -= rx_obj_num; 428 385 429 386 rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num, 430 387 GFP_KERNEL); ··· 495 326 mcp251xfd_ring_free(priv); 496 327 return -ENOMEM; 497 328 } 329 + 498 330 rx_ring->obj_num = rx_obj_num; 499 331 rx_ring->obj_size = rx_obj_size; 500 332 priv->rx[i] = rx_ring; 501 - 502 - ram_free -= rx_ring->obj_num * rx_ring->obj_size; 503 333 } 504 334 priv->rx_ring_num = i; 335 + 336 + hrtimer_init(&priv->rx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 337 + priv->rx_irq_timer.function = mcp251xfd_rx_irq_timer; 338 + 339 + hrtimer_init(&priv->tx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 340 + priv->tx_irq_timer.function = mcp251xfd_tx_irq_timer; 505 341 506 342 return 0; 507 343 }
+11 -1
drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
··· 254 254 int err, n; 255 255 256 256 mcp251xfd_for_each_rx_ring(priv, ring, n) { 257 - if (!(priv->regs_status.rxif & BIT(ring->fifo_nr))) 257 + /* - if RX IRQ coalescing is active always handle ring 0 258 + * - only handle rings if RX IRQ is active 259 + */ 260 + if ((ring->nr > 0 || !priv->rx_obj_num_coalesce_irq) && 261 + !(priv->regs_status.rxif & BIT(ring->fifo_nr))) 258 262 continue; 259 263 260 264 err = mcp251xfd_handle_rxif_ring(priv, ring); 261 265 if (err) 262 266 return err; 263 267 } 268 + 269 + if (priv->rx_coalesce_usecs_irq) 270 + hrtimer_start(&priv->rx_irq_timer, 271 + ns_to_ktime(priv->rx_coalesce_usecs_irq * 272 + NSEC_PER_USEC), 273 + HRTIMER_MODE_REL); 264 274 265 275 return 0; 266 276 }
+6
drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
··· 256 256 netif_wake_queue(priv->ndev); 257 257 } 258 258 259 + if (priv->tx_coalesce_usecs_irq) 260 + hrtimer_start(&priv->tx_irq_timer, 261 + ns_to_ktime(priv->tx_coalesce_usecs_irq * 262 + NSEC_PER_USEC), 263 + HRTIMER_MODE_REL); 264 + 259 265 return 0; 260 266 }
+50 -21
drivers/net/can/spi/mcp251xfd/mcp251xfd.h
··· 367 367 #define MCP251XFD_REG_DEVID_ID_MASK GENMASK(7, 4) 368 368 #define MCP251XFD_REG_DEVID_REV_MASK GENMASK(3, 0) 369 369 370 - /* number of TX FIFO objects, depending on CAN mode 371 - * 372 - * FIFO setup: tef: 8*12 bytes = 96 bytes, tx: 8*16 bytes = 128 bytes 373 - * FIFO setup: tef: 4*12 bytes = 48 bytes, tx: 4*72 bytes = 288 bytes 374 - */ 375 - #define MCP251XFD_RX_OBJ_NUM_MAX 32 376 - #define MCP251XFD_TX_OBJ_NUM_CAN 8 377 - #define MCP251XFD_TX_OBJ_NUM_CANFD 4 378 - 379 - #if MCP251XFD_TX_OBJ_NUM_CAN > MCP251XFD_TX_OBJ_NUM_CANFD 380 - #define MCP251XFD_TX_OBJ_NUM_MAX MCP251XFD_TX_OBJ_NUM_CAN 381 - #else 382 - #define MCP251XFD_TX_OBJ_NUM_MAX MCP251XFD_TX_OBJ_NUM_CANFD 383 - #endif 384 - 385 - #define MCP251XFD_NAPI_WEIGHT 32 386 - 387 370 /* SPI commands */ 388 371 #define MCP251XFD_SPI_INSTRUCTION_RESET 0x0000 389 372 #define MCP251XFD_SPI_INSTRUCTION_WRITE 0x2000 ··· 387 404 #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US) 388 405 #define MCP251XFD_POLL_SLEEP_US (10) 389 406 #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) 407 + 408 + /* Misc */ 409 + #define MCP251XFD_NAPI_WEIGHT 32 390 410 #define MCP251XFD_SOFTRESET_RETRIES_MAX 3 391 411 #define MCP251XFD_READ_CRC_RETRIES_MAX 3 392 412 #define MCP251XFD_ECC_CNT_MAX 2 ··· 398 412 399 413 /* FIFO and Ring */ 400 414 #define MCP251XFD_FIFO_TEF_NUM 1U 401 - #define MCP251XFD_FIFO_RX_NUM_MAX 1U 415 + #define MCP251XFD_FIFO_RX_NUM 3U 402 416 #define MCP251XFD_FIFO_TX_NUM 1U 417 + 418 + #define MCP251XFD_FIFO_DEPTH 32U 419 + 420 + #define MCP251XFD_RX_OBJ_NUM_MIN 16U 421 + #define MCP251XFD_RX_OBJ_NUM_MAX (MCP251XFD_FIFO_RX_NUM * MCP251XFD_FIFO_DEPTH) 422 + #define MCP251XFD_RX_FIFO_DEPTH_MIN 4U 423 + #define MCP251XFD_RX_FIFO_DEPTH_COALESCE_MIN 8U 424 + 425 + #define MCP251XFD_TX_OBJ_NUM_MIN 2U 426 + #define MCP251XFD_TX_OBJ_NUM_MAX 16U 427 + #define MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT 8U 428 + #define MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT 4U 429 + #define MCP251XFD_TX_FIFO_DEPTH_MIN 2U 430 + #define MCP251XFD_TX_FIFO_DEPTH_COALESCE_MIN 2U 403 431 404 432 static_assert(MCP251XFD_FIFO_TEF_NUM == 1U); 405 433 static_assert(MCP251XFD_FIFO_TEF_NUM == MCP251XFD_FIFO_TX_NUM); 406 - static_assert(MCP251XFD_FIFO_RX_NUM_MAX <= 4U); 434 + static_assert(MCP251XFD_FIFO_RX_NUM <= 4U); 407 435 408 436 /* Silence TX MAB overflow warnings */ 409 437 #define MCP251XFD_QUIRK_MAB_NO_WARN BIT(0) ··· 519 519 /* u8 obj_num equals tx_ring->obj_num */ 520 520 /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ 521 521 522 + union mcp251xfd_write_reg_buf irq_enable_buf; 523 + struct spi_transfer irq_enable_xfer; 524 + struct spi_message irq_enable_msg; 525 + 522 526 union mcp251xfd_write_reg_buf uinc_buf; 527 + union mcp251xfd_write_reg_buf uinc_irq_disable_buf; 523 528 struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX]; 524 529 }; 525 530 ··· 552 547 u8 obj_num; 553 548 u8 obj_size; 554 549 550 + union mcp251xfd_write_reg_buf irq_enable_buf; 551 + struct spi_transfer irq_enable_xfer; 552 + struct spi_message irq_enable_msg; 553 + 555 554 union mcp251xfd_write_reg_buf uinc_buf; 556 - struct spi_transfer uinc_xfer[MCP251XFD_RX_OBJ_NUM_MAX]; 555 + union mcp251xfd_write_reg_buf uinc_irq_disable_buf; 556 + struct spi_transfer uinc_xfer[MCP251XFD_FIFO_DEPTH]; 557 557 struct mcp251xfd_hw_rx_obj_canfd obj[]; 558 558 }; 559 559 ··· 594 584 u32 quirks; 595 585 }; 596 586 587 + enum mcp251xfd_flags { 588 + MCP251XFD_FLAGS_DOWN, 589 + MCP251XFD_FLAGS_FD_MODE, 590 + 591 + __MCP251XFD_FLAGS_SIZE__ 592 + }; 593 + 597 594 struct mcp251xfd_priv { 598 595 struct can_priv can; 599 596 struct can_rx_offload offload; ··· 623 606 u32 spi_max_speed_hz_slow; 624 607 625 608 struct mcp251xfd_tef_ring tef[MCP251XFD_FIFO_TEF_NUM]; 626 - struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM_MAX]; 609 + struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM]; 627 610 struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM]; 628 611 612 + DECLARE_BITMAP(flags, __MCP251XFD_FLAGS_SIZE__); 613 + 629 614 u8 rx_ring_num; 615 + u8 rx_obj_num; 616 + u8 rx_obj_num_coalesce_irq; 617 + u8 tx_obj_num_coalesce_irq; 618 + 619 + u32 rx_coalesce_usecs_irq; 620 + u32 tx_coalesce_usecs_irq; 621 + struct hrtimer rx_irq_timer; 622 + struct hrtimer tx_irq_timer; 630 623 631 624 struct mcp251xfd_ecc ecc; 632 625 struct mcp251xfd_regs_status regs_status; ··· 918 891 u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size, 919 892 const void *data, size_t data_size); 920 893 u16 mcp251xfd_crc16_compute(const void *data, size_t data_size); 894 + void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv); 921 895 int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv); 896 + extern const struct can_ram_config mcp251xfd_ram_config; 922 897 int mcp251xfd_ring_init(struct mcp251xfd_priv *priv); 923 898 void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); 924 899 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv);
+1 -1
drivers/net/can/vxcan.c
··· 57 57 if (skb) { 58 58 consume_skb(oskb); 59 59 } else { 60 - kfree(oskb); 60 + kfree_skb(oskb); 61 61 goto out_unlock; 62 62 } 63 63