/* Message with data needs at least two words (for header & data). */
 #define MLXBF_TMFIFO_DATA_MIN_WORDS            2
 
+/* ACPI UID for BlueField-3. */
+#define TMFIFO_BF3_UID                         1
+
 struct mlxbf_tmfifo;
 
 /**
        int index;
 };
 
+/**
+ * mlxbf_tmfifo_io - Structure of the TmFifo IO resource (for both rx & tx)
+ * @ctl: control register offset (TMFIFO_RX_CTL / TMFIFO_TX_CTL)
+ * @sts: status register offset (TMFIFO_RX_STS / TMFIFO_TX_STS)
+ * @data: data register offset (TMFIFO_RX_DATA / TMFIFO_TX_DATA)
+ */
+struct mlxbf_tmfifo_io {
+       void __iomem *ctl;
+       void __iomem *sts;
+       void __iomem *data;
+};
+
 /**
  * mlxbf_tmfifo - Structure of the TmFifo
  * @vdev: array of the virtual devices running over the TmFifo
  * @lock: lock to protect the TmFifo access
- * @rx_base: mapped register base address for the Rx FIFO
- * @tx_base: mapped register base address for the Tx FIFO
+ * @res0: mapped resource block 0
+ * @res1: mapped resource block 1
+ * @rx: rx io resource
+ * @tx: tx io resource
  * @rx_fifo_size: number of entries of the Rx FIFO
  * @tx_fifo_size: number of entries of the Tx FIFO
  * @pend_events: pending bits for deferred events
 struct mlxbf_tmfifo {
        struct mlxbf_tmfifo_vdev *vdev[MLXBF_TMFIFO_VDEV_MAX];
        struct mutex lock;              /* TmFifo lock */
-       void __iomem *rx_base;
-       void __iomem *tx_base;
+       void __iomem *res0;
+       void __iomem *res1;
+       struct mlxbf_tmfifo_io rx;
+       struct mlxbf_tmfifo_io tx;
        int rx_fifo_size;
        int tx_fifo_size;
        unsigned long pend_events;
 {
        u64 sts;
 
-       sts = readq(fifo->rx_base + MLXBF_TMFIFO_RX_STS);
+       sts = readq(fifo->rx.sts);
        return FIELD_GET(MLXBF_TMFIFO_RX_STS__COUNT_MASK, sts);
 }
 
        else
                tx_reserve = 1;
 
-       sts = readq(fifo->tx_base + MLXBF_TMFIFO_TX_STS);
+       sts = readq(fifo->tx.sts);
        count = FIELD_GET(MLXBF_TMFIFO_TX_STS__COUNT_MASK, sts);
        return fifo->tx_fifo_size - tx_reserve - count;
 }
        /* Write header. */
        hdr.type = VIRTIO_ID_CONSOLE;
        hdr.len = htons(size);
-       writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA);
+       writeq(*(u64 *)&hdr, fifo->tx.data);
 
        /* Use spin-lock to protect the 'cons->tx_buf'. */
        spin_lock_irqsave(&fifo->spin_lock[0], flags);
                        memcpy((u8 *)&data + seg, cons->tx_buf.buf,
                               sizeof(u64) - seg);
                }
-               writeq(data, fifo->tx_base + MLXBF_TMFIFO_TX_DATA);
+               writeq(data, fifo->tx.data);
 
                if (size >= sizeof(u64)) {
                        cons->tx_buf.tail = (cons->tx_buf.tail + sizeof(u64)) %
 
        /* Read a word from FIFO for Rx. */
        if (is_rx)
-               data = readq(fifo->rx_base + MLXBF_TMFIFO_RX_DATA);
+               data = readq(fifo->rx.data);
 
        if (vring->cur_len + sizeof(u64) <= len) {
                /* The whole word. */
 
        /* Write the word into FIFO for Tx. */
        if (!is_rx)
-               writeq(data, fifo->tx_base + MLXBF_TMFIFO_TX_DATA);
+               writeq(data, fifo->tx.data);
 }
 
 /*
        /* Read/Write packet header. */
        if (is_rx) {
                /* Drain one word from the FIFO. */
-               *(u64 *)&hdr = readq(fifo->rx_base + MLXBF_TMFIFO_RX_DATA);
+               *(u64 *)&hdr = readq(fifo->rx.data);
 
                /* Skip the length 0 packets (keepalive). */
                if (hdr.len == 0)
                hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ?
                            VIRTIO_ID_NET : VIRTIO_ID_CONSOLE;
                hdr.len = htons(vring->pkt_len - hdr_len);
-               writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA);
+               writeq(*(u64 *)&hdr, fifo->tx.data);
        }
 
        vring->cur_len = hdr_len;
        u64 ctl;
 
        /* Get Tx FIFO size and set the low/high watermark. */
-       ctl = readq(fifo->tx_base + MLXBF_TMFIFO_TX_CTL);
+       ctl = readq(fifo->tx.ctl);
        fifo->tx_fifo_size =
                FIELD_GET(MLXBF_TMFIFO_TX_CTL__MAX_ENTRIES_MASK, ctl);
        ctl = (ctl & ~MLXBF_TMFIFO_TX_CTL__LWM_MASK) |
        ctl = (ctl & ~MLXBF_TMFIFO_TX_CTL__HWM_MASK) |
                FIELD_PREP(MLXBF_TMFIFO_TX_CTL__HWM_MASK,
                           fifo->tx_fifo_size - 1);
-       writeq(ctl, fifo->tx_base + MLXBF_TMFIFO_TX_CTL);
+       writeq(ctl, fifo->tx.ctl);
 
        /* Get Rx FIFO size and set the low/high watermark. */
-       ctl = readq(fifo->rx_base + MLXBF_TMFIFO_RX_CTL);
+       ctl = readq(fifo->rx.ctl);
        fifo->rx_fifo_size =
                FIELD_GET(MLXBF_TMFIFO_RX_CTL__MAX_ENTRIES_MASK, ctl);
        ctl = (ctl & ~MLXBF_TMFIFO_RX_CTL__LWM_MASK) |
                FIELD_PREP(MLXBF_TMFIFO_RX_CTL__LWM_MASK, 0);
        ctl = (ctl & ~MLXBF_TMFIFO_RX_CTL__HWM_MASK) |
                FIELD_PREP(MLXBF_TMFIFO_RX_CTL__HWM_MASK, 1);
-       writeq(ctl, fifo->rx_base + MLXBF_TMFIFO_RX_CTL);
+       writeq(ctl, fifo->rx.ctl);
 }
 
 static void mlxbf_tmfifo_cleanup(struct mlxbf_tmfifo *fifo)
        struct virtio_net_config net_config;
        struct device *dev = &pdev->dev;
        struct mlxbf_tmfifo *fifo;
+       u64 dev_id;
        int i, rc;
 
+       rc = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &dev_id);
+       if (rc) {
+               dev_err(dev, "Cannot retrieve UID\n");
+               return rc;
+       }
+
        fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL);
        if (!fifo)
                return -ENOMEM;
        mutex_init(&fifo->lock);
 
        /* Get the resource of the Rx FIFO. */
-       fifo->rx_base = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(fifo->rx_base))
-               return PTR_ERR(fifo->rx_base);
+       fifo->res0 = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(fifo->res0))
+               return PTR_ERR(fifo->res0);
 
        /* Get the resource of the Tx FIFO. */
-       fifo->tx_base = devm_platform_ioremap_resource(pdev, 1);
-       if (IS_ERR(fifo->tx_base))
-               return PTR_ERR(fifo->tx_base);
+       fifo->res1 = devm_platform_ioremap_resource(pdev, 1);
+       if (IS_ERR(fifo->res1))
+               return PTR_ERR(fifo->res1);
+
+       if (dev_id == TMFIFO_BF3_UID) {
+               fifo->rx.ctl = fifo->res1 + MLXBF_TMFIFO_RX_CTL_BF3;
+               fifo->rx.sts = fifo->res1 + MLXBF_TMFIFO_RX_STS_BF3;
+               fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA_BF3;
+               fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL_BF3;
+               fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS_BF3;
+               fifo->tx.data = fifo->res0 + MLXBF_TMFIFO_TX_DATA_BF3;
+       } else {
+               fifo->rx.ctl = fifo->res0 + MLXBF_TMFIFO_RX_CTL;
+               fifo->rx.sts = fifo->res0 + MLXBF_TMFIFO_RX_STS;
+               fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA;
+               fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL;
+               fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS;
+               fifo->tx.data = fifo->res1 + MLXBF_TMFIFO_TX_DATA;
+       }
 
        platform_set_drvdata(pdev, fifo);