fpi * TXB_ELEMENT_SIZE + offset);
 }
 
+static inline u32 m_can_txe_fifo_read(const struct m_can_priv *priv,
+                                     u32 fgi,
+                                     u32 offset) {
+       return readl(priv->mram_base + priv->mcfg[MRAM_TXE].off +
+                       fgi * TXE_ELEMENT_SIZE + offset);
+}
+
+static inline bool m_can_tx_fifo_full(const struct m_can_priv *priv)
+{
+               return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF);
+}
+
 static inline void m_can_config_endisable(const struct m_can_priv *priv,
                                          bool enable)
 {
  * - configure rx fifo
  * - accept non-matching frame into fifo 0
  * - configure tx buffer
+ *             - >= v3.1.x: TX FIFO is used
  * - configure mode
  * - setup bittiming
  */
        /* Accept Non-matching Frames Into FIFO 0 */
        m_can_write(priv, M_CAN_GFC, 0x0);
 
-       /* only support one Tx Buffer currently */
-       m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_SHIFT) |
-                   priv->mcfg[MRAM_TXB].off);
+       if (priv->version == 30) {
+               /* only support one Tx Buffer currently */
+               m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_SHIFT) |
+                               priv->mcfg[MRAM_TXB].off);
+       } else {
+               /* TX FIFO is used for newer IP Core versions */
+               m_can_write(priv, M_CAN_TXBC,
+                           (priv->mcfg[MRAM_TXB].num << TXBC_TFQS_SHIFT) |
+                           (priv->mcfg[MRAM_TXB].off));
+       }
 
        /* support 64 bytes payload */
        m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES);
 
-       m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_SHIFT) |
-                   priv->mcfg[MRAM_TXE].off);
+       /* TX Event FIFO */
+       if (priv->version == 30) {
+               m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_SHIFT) |
+                               priv->mcfg[MRAM_TXE].off);
+       } else {
+               /* Full TX Event FIFO is used */
+               m_can_write(priv, M_CAN_TXEFC,
+                           ((priv->mcfg[MRAM_TXE].num << TXEFC_EFS_SHIFT)
+                            & TXEFC_EFS_MASK) |
+                           priv->mcfg[MRAM_TXE].off);
+       }
 
        /* rx fifo configuration, blocking mode, fifo size 1 */
        m_can_write(priv, M_CAN_RXF0C,