/* TEF- and TX-FIFO have same number of objects */
        *base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);
 
+       /* FIFO IRQ enable */
+       addr = MCP251XFD_REG_TEFCON;
+       val = MCP251XFD_REG_TEFCON_TEFOVIE | MCP251XFD_REG_TEFCON_TEFNEIE;
+
+       len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->irq_enable_buf,
+                                             addr, val, val);
+       tef_ring->irq_enable_xfer.tx_buf = &tef_ring->irq_enable_buf;
+       tef_ring->irq_enable_xfer.len = len;
+       spi_message_init_with_transfers(&tef_ring->irq_enable_msg,
+                                       &tef_ring->irq_enable_xfer, 1);
+
        /* FIFO increment TEF tail pointer */
        addr = MCP251XFD_REG_TEFCON;
        val = MCP251XFD_REG_TEFCON_UINC;
         * message.
         */
        xfer->cs_change = 0;
+
+       if (priv->tx_coalesce_usecs_irq || priv->tx_obj_num_coalesce_irq) {
+               val = MCP251XFD_REG_TEFCON_UINC |
+                       MCP251XFD_REG_TEFCON_TEFOVIE |
+                       MCP251XFD_REG_TEFCON_TEFHIE;
+
+               len = mcp251xfd_cmd_prepare_write_reg(priv,
+                                                     &tef_ring->uinc_irq_disable_buf,
+                                                     addr, val, val);
+               xfer->tx_buf = &tef_ring->uinc_irq_disable_buf;
+               xfer->len = len;
+       }
 }
 
 static void
         */
        priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);
 
-       netdev_dbg(priv->ndev,
-                  "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes\n",
-                  mcp251xfd_get_tef_obj_addr(0),
-                  priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
-                  priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
+       if (priv->tx_obj_num_coalesce_irq) {
+               netdev_dbg(priv->ndev,
+                          "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes (coalesce)\n",
+                          mcp251xfd_get_tef_obj_addr(0),
+                          priv->tx_obj_num_coalesce_irq,
+                          sizeof(struct mcp251xfd_hw_tef_obj),
+                          priv->tx_obj_num_coalesce_irq *
+                          sizeof(struct mcp251xfd_hw_tef_obj));
+
+               netdev_dbg(priv->ndev,
+                          "                         0x%03x: %2d*%zu bytes = %4zu bytes\n",
+                          mcp251xfd_get_tef_obj_addr(priv->tx_obj_num_coalesce_irq),
+                          priv->tx->obj_num - priv->tx_obj_num_coalesce_irq,
+                          sizeof(struct mcp251xfd_hw_tef_obj),
+                          (priv->tx->obj_num - priv->tx_obj_num_coalesce_irq) *
+                          sizeof(struct mcp251xfd_hw_tef_obj));
+       } else {
+               netdev_dbg(priv->ndev,
+                          "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes\n",
+                          mcp251xfd_get_tef_obj_addr(0),
+                          priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
+                          priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
+       }
 
        mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
                if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) {
        return HRTIMER_NORESTART;
 }
 
+static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t)
+{
+       struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
+                                                  tx_irq_timer);
+       struct mcp251xfd_tef_ring *ring = priv->tef;
+
+       if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
+               return HRTIMER_NORESTART;
+
+       spi_async(priv->spi, &ring->irq_enable_msg);
+
+       return HRTIMER_NORESTART;
+}
+
 const struct can_ram_config mcp251xfd_ram_config = {
        .rx = {
                .size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_rx_obj_can),
        hrtimer_init(&priv->rx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        priv->rx_irq_timer.function = mcp251xfd_rx_irq_timer;
 
+       hrtimer_init(&priv->tx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       priv->tx_irq_timer.function = mcp251xfd_tx_irq_timer;
+
        return 0;
 }
 
        /* u8 obj_num equals tx_ring->obj_num */
        /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
 
+       union mcp251xfd_write_reg_buf irq_enable_buf;
+       struct spi_transfer irq_enable_xfer;
+       struct spi_message irq_enable_msg;
+
        union mcp251xfd_write_reg_buf uinc_buf;
+       union mcp251xfd_write_reg_buf uinc_irq_disable_buf;
        struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX];
 };
 
        u8 rx_ring_num;
        u8 rx_obj_num;
        u8 rx_obj_num_coalesce_irq;
+       u8 tx_obj_num_coalesce_irq;
 
        u32 rx_coalesce_usecs_irq;
+       u32 tx_coalesce_usecs_irq;
        struct hrtimer rx_irq_timer;
+       struct hrtimer tx_irq_timer;
 
        struct mcp251xfd_ecc ecc;
        struct mcp251xfd_regs_status regs_status;