qtnfmac_pcie: move Pearl pcie sources to pcie-specific directory
authorIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Mon, 24 Sep 2018 22:15:05 +0000 (15:15 -0700)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 1 Oct 2018 15:39:59 +0000 (18:39 +0300)
In preparation to extract common qtnfmac PCIe driver sources into a
separate file, move existing Pearl-specific pcie driver sources to pcie/
directory.

Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/quantenna/qtnfmac/Makefile
drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c [new file with mode: 0644]
drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h [new file with mode: 0644]
drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h [new file with mode: 0644]
drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h [new file with mode: 0644]
drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c [deleted file]
drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h [deleted file]
drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h [deleted file]
drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h [deleted file]

index 97f760a..9eeddea 100644 (file)
@@ -23,6 +23,6 @@ obj-$(CONFIG_QTNFMAC_PEARL_PCIE) += qtnfmac_pearl_pcie.o
 
 qtnfmac_pearl_pcie-objs += \
        shm_ipc.o \
-       pearl/pcie.o
+       pcie/pearl_pcie.o
 
 qtnfmac_pearl_pcie-$(CONFIG_DEBUG_FS) += debug.o
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
new file mode 100644 (file)
index 0000000..269a6e4
--- /dev/null
@@ -0,0 +1,1494 @@
+/*
+ * Copyright (c) 2015-2016 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/crc32.h>
+#include <linux/spinlock.h>
+#include <linux/circ_buf.h>
+#include <linux/log2.h>
+
+#include "qtn_hw_ids.h"
+#include "pearl_pcie_bus_priv.h"
+#include "core.h"
+#include "bus.h"
+#include "debug.h"
+
+static bool use_msi = true;
+module_param(use_msi, bool, 0644);
+MODULE_PARM_DESC(use_msi, "set 0 to use legacy interrupt");
+
+static unsigned int tx_bd_size_param = 32;
+module_param(tx_bd_size_param, uint, 0644);
+MODULE_PARM_DESC(tx_bd_size_param, "Tx descriptors queue size, power of two");
+
+static unsigned int rx_bd_size_param = 256;
+module_param(rx_bd_size_param, uint, 0644);
+MODULE_PARM_DESC(rx_bd_size_param, "Rx descriptors queue size, power of two");
+
+static u8 flashboot = 1;
+module_param(flashboot, byte, 0644);
+MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS");
+
+#define DRV_NAME       "qtnfmac_pearl_pcie"
+
+static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg)
+{
+       writel(val, basereg);
+
+       /* flush posted write */
+       readl(basereg);
+}
+
+static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       priv->pcie_irq_mask = (PCIE_HDP_INT_RX_BITS | PCIE_HDP_INT_TX_BITS);
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       writel(0x0, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       priv->pcie_irq_mask |= PCIE_HDP_INT_RX_BITS;
+       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       priv->pcie_irq_mask &= ~PCIE_HDP_INT_RX_BITS;
+       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_en_txdone_irq(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       priv->pcie_irq_mask |= PCIE_HDP_INT_TX_BITS;
+       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_bus_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->irq_lock, flags);
+       priv->pcie_irq_mask &= ~PCIE_HDP_INT_TX_BITS;
+       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       spin_unlock_irqrestore(&priv->irq_lock, flags);
+}
+
+static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv)
+{
+       struct pci_dev *pdev = priv->pdev;
+
+       /* fall back to legacy INTx interrupts by default */
+       priv->msi_enabled = 0;
+
+       /* check if MSI capability is available */
+       if (use_msi) {
+               if (!pci_enable_msi(pdev)) {
+                       pr_debug("MSI interrupt enabled\n");
+                       priv->msi_enabled = 1;
+               } else {
+                       pr_warn("failed to enable MSI interrupts");
+               }
+       }
+
+       if (!priv->msi_enabled) {
+               pr_warn("legacy PCIE interrupts enabled\n");
+               pci_intx(pdev, 1);
+       }
+}
+
+static void qtnf_deassert_intx(struct qtnf_pcie_bus_priv *priv)
+{
+       void __iomem *reg = priv->sysctl_bar + PEARL_PCIE_CFG0_OFFSET;
+       u32 cfg;
+
+       cfg = readl(reg);
+       cfg &= ~PEARL_ASSERT_INTX;
+       qtnf_non_posted_write(cfg, reg);
+}
+
+static void qtnf_reset_card(struct qtnf_pcie_bus_priv *priv)
+{
+       const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET);
+       void __iomem *reg = priv->sysctl_bar +
+                           QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET;
+
+       qtnf_non_posted_write(data, reg);
+       msleep(QTN_EP_RESET_WAIT_MS);
+       pci_restore_state(priv->pdev);
+}
+
+static void qtnf_ipc_gen_ep_int(void *arg)
+{
+       const struct qtnf_pcie_bus_priv *priv = arg;
+       const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_IPC_IRQ);
+       void __iomem *reg = priv->sysctl_bar +
+                           QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET;
+
+       qtnf_non_posted_write(data, reg);
+}
+
+static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index)
+{
+       void __iomem *vaddr;
+       dma_addr_t busaddr;
+       size_t len;
+       int ret;
+
+       ret = pcim_iomap_regions(priv->pdev, 1 << index, DRV_NAME);
+       if (ret)
+               return IOMEM_ERR_PTR(ret);
+
+       busaddr = pci_resource_start(priv->pdev, index);
+       len = pci_resource_len(priv->pdev, index);
+       vaddr = pcim_iomap_table(priv->pdev)[index];
+       if (!vaddr)
+               return IOMEM_ERR_PTR(-ENOMEM);
+
+       pr_debug("BAR%u vaddr=0x%p busaddr=%pad len=%u\n",
+                index, vaddr, &busaddr, (int)len);
+
+       return vaddr;
+}
+
+static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len)
+{
+       struct qtnf_pcie_bus_priv *priv = arg;
+       struct qtnf_bus *bus = pci_get_drvdata(priv->pdev);
+       struct sk_buff *skb;
+
+       if (unlikely(len == 0)) {
+               pr_warn("zero length packet received\n");
+               return;
+       }
+
+       skb = __dev_alloc_skb(len, GFP_KERNEL);
+
+       if (unlikely(!skb)) {
+               pr_err("failed to allocate skb\n");
+               return;
+       }
+
+       skb_put_data(skb, buf, len);
+
+       qtnf_trans_handle_rx_ctl_packet(bus, skb);
+}
+
+static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv)
+{
+       struct qtnf_shm_ipc_region __iomem *ipc_tx_reg;
+       struct qtnf_shm_ipc_region __iomem *ipc_rx_reg;
+       const struct qtnf_shm_ipc_int ipc_int = { qtnf_ipc_gen_ep_int, priv };
+       const struct qtnf_shm_ipc_rx_callback rx_callback = {
+                                       qtnf_pcie_control_rx_callback, priv };
+
+       ipc_tx_reg = &priv->bda->bda_shm_reg1;
+       ipc_rx_reg = &priv->bda->bda_shm_reg2;
+
+       qtnf_shm_ipc_init(&priv->shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND,
+                         ipc_tx_reg, priv->workqueue,
+                         &ipc_int, &rx_callback);
+       qtnf_shm_ipc_init(&priv->shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND,
+                         ipc_rx_reg, priv->workqueue,
+                         &ipc_int, &rx_callback);
+
+       return 0;
+}
+
+static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv)
+{
+       qtnf_shm_ipc_free(&priv->shm_ipc_ep_in);
+       qtnf_shm_ipc_free(&priv->shm_ipc_ep_out);
+}
+
+static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv)
+{
+       int ret = -ENOMEM;
+
+       priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR);
+       if (IS_ERR(priv->sysctl_bar)) {
+               pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR);
+               return ret;
+       }
+
+       priv->dmareg_bar = qtnf_map_bar(priv, QTN_DMA_BAR);
+       if (IS_ERR(priv->dmareg_bar)) {
+               pr_err("failed to map BAR%u\n", QTN_DMA_BAR);
+               return ret;
+       }
+
+       priv->epmem_bar = qtnf_map_bar(priv, QTN_SHMEM_BAR);
+       if (IS_ERR(priv->epmem_bar)) {
+               pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR);
+               return ret;
+       }
+
+       priv->pcie_reg_base = priv->dmareg_bar;
+       priv->bda = priv->epmem_bar;
+       writel(priv->msi_enabled, &priv->bda->bda_rc_msi_enabled);
+
+       return 0;
+}
+
+static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv)
+{
+       struct pci_dev *pdev = priv->pdev;
+       struct pci_dev *parent;
+       int mps_p, mps_o, mps_m, mps;
+       int ret;
+
+       /* current mps */
+       mps_o = pcie_get_mps(pdev);
+
+       /* maximum supported mps */
+       mps_m = 128 << pdev->pcie_mpss;
+
+       /* suggested new mps value */
+       mps = mps_m;
+
+       if (pdev->bus && pdev->bus->self) {
+               /* parent (bus) mps */
+               parent = pdev->bus->self;
+
+               if (pci_is_pcie(parent)) {
+                       mps_p = pcie_get_mps(parent);
+                       mps = min(mps_m, mps_p);
+               }
+       }
+
+       ret = pcie_set_mps(pdev, mps);
+       if (ret) {
+               pr_err("failed to set mps to %d, keep using current %d\n",
+                      mps, mps_o);
+               priv->mps = mps_o;
+               return;
+       }
+
+       pr_debug("set mps to %d (was %d, max %d)\n", mps, mps_o, mps_m);
+       priv->mps = mps;
+}
+
+static int qtnf_is_state(__le32 __iomem *reg, u32 state)
+{
+       u32 s = readl(reg);
+
+       return s & state;
+}
+
+static void qtnf_set_state(__le32 __iomem *reg, u32 state)
+{
+       u32 s = readl(reg);
+
+       qtnf_non_posted_write(state | s, reg);
+}
+
+static void qtnf_clear_state(__le32 __iomem *reg, u32 state)
+{
+       u32 s = readl(reg);
+
+       qtnf_non_posted_write(s & ~state, reg);
+}
+
+static int qtnf_poll_state(__le32 __iomem *reg, u32 state, u32 delay_in_ms)
+{
+       u32 timeout = 0;
+
+       while ((qtnf_is_state(reg, state) == 0)) {
+               usleep_range(1000, 1200);
+               if (++timeout > delay_in_ms)
+                       return -1;
+       }
+
+       return 0;
+}
+
+static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv)
+{
+       struct sk_buff **vaddr;
+       int len;
+
+       len = priv->tx_bd_num * sizeof(*priv->tx_skb) +
+               priv->rx_bd_num * sizeof(*priv->rx_skb);
+       vaddr = devm_kzalloc(&priv->pdev->dev, len, GFP_KERNEL);
+
+       if (!vaddr)
+               return -ENOMEM;
+
+       priv->tx_skb = vaddr;
+
+       vaddr += priv->tx_bd_num;
+       priv->rx_skb = vaddr;
+
+       return 0;
+}
+
+static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv)
+{
+       dma_addr_t paddr;
+       void *vaddr;
+       int len;
+
+       len = priv->tx_bd_num * sizeof(struct qtnf_tx_bd) +
+               priv->rx_bd_num * sizeof(struct qtnf_rx_bd);
+
+       vaddr = dmam_alloc_coherent(&priv->pdev->dev, len, &paddr, GFP_KERNEL);
+       if (!vaddr)
+               return -ENOMEM;
+
+       /* tx bd */
+
+       memset(vaddr, 0, len);
+
+       priv->bd_table_vaddr = vaddr;
+       priv->bd_table_paddr = paddr;
+       priv->bd_table_len = len;
+
+       priv->tx_bd_vbase = vaddr;
+       priv->tx_bd_pbase = paddr;
+
+       pr_debug("TX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
+
+       priv->tx_bd_r_index = 0;
+       priv->tx_bd_w_index = 0;
+
+       /* rx bd */
+
+       vaddr = ((struct qtnf_tx_bd *)vaddr) + priv->tx_bd_num;
+       paddr += priv->tx_bd_num * sizeof(struct qtnf_tx_bd);
+
+       priv->rx_bd_vbase = vaddr;
+       priv->rx_bd_pbase = paddr;
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       writel(QTN_HOST_HI32(paddr),
+              PCIE_HDP_TX_HOST_Q_BASE_H(priv->pcie_reg_base));
+#endif
+       writel(QTN_HOST_LO32(paddr),
+              PCIE_HDP_TX_HOST_Q_BASE_L(priv->pcie_reg_base));
+       writel(priv->rx_bd_num | (sizeof(struct qtnf_rx_bd)) << 16,
+              PCIE_HDP_TX_HOST_Q_SZ_CTRL(priv->pcie_reg_base));
+
+       pr_debug("RX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
+
+       return 0;
+}
+
+static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 index)
+{
+       struct qtnf_rx_bd *rxbd;
+       struct sk_buff *skb;
+       dma_addr_t paddr;
+
+       skb = __netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE, GFP_ATOMIC);
+       if (!skb) {
+               priv->rx_skb[index] = NULL;
+               return -ENOMEM;
+       }
+
+       priv->rx_skb[index] = skb;
+       rxbd = &priv->rx_bd_vbase[index];
+
+       paddr = pci_map_single(priv->pdev, skb->data,
+                              SKB_BUF_SIZE, PCI_DMA_FROMDEVICE);
+       if (pci_dma_mapping_error(priv->pdev, paddr)) {
+               pr_err("skb DMA mapping error: %pad\n", &paddr);
+               return -ENOMEM;
+       }
+
+       /* keep rx skb paddrs in rx buffer descriptors for cleanup purposes */
+       rxbd->addr = cpu_to_le32(QTN_HOST_LO32(paddr));
+       rxbd->addr_h = cpu_to_le32(QTN_HOST_HI32(paddr));
+       rxbd->info = 0x0;
+
+       priv->rx_bd_w_index = index;
+
+       /* sync up all descriptor updates */
+       wmb();
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       writel(QTN_HOST_HI32(paddr),
+              PCIE_HDP_HHBM_BUF_PTR_H(priv->pcie_reg_base));
+#endif
+       writel(QTN_HOST_LO32(paddr),
+              PCIE_HDP_HHBM_BUF_PTR(priv->pcie_reg_base));
+
+       writel(index, PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base));
+       return 0;
+}
+
+static int alloc_rx_buffers(struct qtnf_pcie_bus_priv *priv)
+{
+       u16 i;
+       int ret = 0;
+
+       memset(priv->rx_bd_vbase, 0x0,
+              priv->rx_bd_num * sizeof(struct qtnf_rx_bd));
+
+       for (i = 0; i < priv->rx_bd_num; i++) {
+               ret = skb2rbd_attach(priv, i);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+/* all rx/tx activity should have ceased before calling this function */
+static void qtnf_free_xfer_buffers(struct qtnf_pcie_bus_priv *priv)
+{
+       struct qtnf_tx_bd *txbd;
+       struct qtnf_rx_bd *rxbd;
+       struct sk_buff *skb;
+       dma_addr_t paddr;
+       int i;
+
+       /* free rx buffers */
+       for (i = 0; i < priv->rx_bd_num; i++) {
+               if (priv->rx_skb && priv->rx_skb[i]) {
+                       rxbd = &priv->rx_bd_vbase[i];
+                       skb = priv->rx_skb[i];
+                       paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h),
+                                             le32_to_cpu(rxbd->addr));
+                       pci_unmap_single(priv->pdev, paddr, SKB_BUF_SIZE,
+                                        PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb_any(skb);
+                       priv->rx_skb[i] = NULL;
+               }
+       }
+
+       /* free tx buffers */
+       for (i = 0; i < priv->tx_bd_num; i++) {
+               if (priv->tx_skb && priv->tx_skb[i]) {
+                       txbd = &priv->tx_bd_vbase[i];
+                       skb = priv->tx_skb[i];
+                       paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
+                                             le32_to_cpu(txbd->addr));
+                       pci_unmap_single(priv->pdev, paddr, skb->len,
+                                        PCI_DMA_TODEVICE);
+                       dev_kfree_skb_any(skb);
+                       priv->tx_skb[i] = NULL;
+               }
+       }
+}
+
+static int qtnf_hhbm_init(struct qtnf_pcie_bus_priv *priv)
+{
+       u32 val;
+
+       val = readl(PCIE_HHBM_CONFIG(priv->pcie_reg_base));
+       val |= HHBM_CONFIG_SOFT_RESET;
+       writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base));
+       usleep_range(50, 100);
+       val &= ~HHBM_CONFIG_SOFT_RESET;
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       val |= HHBM_64BIT;
+#endif
+       writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base));
+       writel(priv->rx_bd_num, PCIE_HHBM_Q_LIMIT_REG(priv->pcie_reg_base));
+
+       return 0;
+}
+
+static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv)
+{
+       int ret;
+       u32 val;
+
+       priv->tx_bd_num = tx_bd_size_param;
+       priv->rx_bd_num = rx_bd_size_param;
+       priv->rx_bd_w_index = 0;
+       priv->rx_bd_r_index = 0;
+
+       if (!priv->tx_bd_num || !is_power_of_2(priv->tx_bd_num)) {
+               pr_err("tx_bd_size_param %u is not power of two\n",
+                      priv->tx_bd_num);
+               return -EINVAL;
+       }
+
+       val = priv->tx_bd_num * sizeof(struct qtnf_tx_bd);
+       if (val > PCIE_HHBM_MAX_SIZE) {
+               pr_err("tx_bd_size_param %u is too large\n",
+                      priv->tx_bd_num);
+               return -EINVAL;
+       }
+
+       if (!priv->rx_bd_num || !is_power_of_2(priv->rx_bd_num)) {
+               pr_err("rx_bd_size_param %u is not power of two\n",
+                      priv->rx_bd_num);
+               return -EINVAL;
+       }
+
+       val = priv->rx_bd_num * sizeof(dma_addr_t);
+       if (val > PCIE_HHBM_MAX_SIZE) {
+               pr_err("rx_bd_size_param %u is too large\n",
+                      priv->rx_bd_num);
+               return -EINVAL;
+       }
+
+       ret = qtnf_hhbm_init(priv);
+       if (ret) {
+               pr_err("failed to init h/w queues\n");
+               return ret;
+       }
+
+       ret = alloc_skb_array(priv);
+       if (ret) {
+               pr_err("failed to allocate skb array\n");
+               return ret;
+       }
+
+       ret = alloc_bd_table(priv);
+       if (ret) {
+               pr_err("failed to allocate bd table\n");
+               return ret;
+       }
+
+       ret = alloc_rx_buffers(priv);
+       if (ret) {
+               pr_err("failed to allocate rx buffers\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv)
+{
+       struct qtnf_tx_bd *txbd;
+       struct sk_buff *skb;
+       unsigned long flags;
+       dma_addr_t paddr;
+       u32 tx_done_index;
+       int count = 0;
+       int i;
+
+       spin_lock_irqsave(&priv->tx_reclaim_lock, flags);
+
+       tx_done_index = readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
+                       & (priv->tx_bd_num - 1);
+
+       i = priv->tx_bd_r_index;
+
+       while (CIRC_CNT(tx_done_index, i, priv->tx_bd_num)) {
+               skb = priv->tx_skb[i];
+               if (likely(skb)) {
+                       txbd = &priv->tx_bd_vbase[i];
+                       paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
+                                             le32_to_cpu(txbd->addr));
+                       pci_unmap_single(priv->pdev, paddr, skb->len,
+                                        PCI_DMA_TODEVICE);
+
+                       if (skb->dev) {
+                               qtnf_update_tx_stats(skb->dev, skb);
+                               if (unlikely(priv->tx_stopped)) {
+                                       qtnf_wake_all_queues(skb->dev);
+                                       priv->tx_stopped = 0;
+                               }
+                       }
+
+                       dev_kfree_skb_any(skb);
+               }
+
+               priv->tx_skb[i] = NULL;
+               count++;
+
+               if (++i >= priv->tx_bd_num)
+                       i = 0;
+       }
+
+       priv->tx_reclaim_done += count;
+       priv->tx_reclaim_req++;
+       priv->tx_bd_r_index = i;
+
+       spin_unlock_irqrestore(&priv->tx_reclaim_lock, flags);
+}
+
+static int qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv)
+{
+       if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
+                       priv->tx_bd_num)) {
+               qtnf_pcie_data_tx_reclaim(priv);
+
+               if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
+                               priv->tx_bd_num)) {
+                       pr_warn_ratelimited("reclaim full Tx queue\n");
+                       priv->tx_full_count++;
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       dma_addr_t txbd_paddr, skb_paddr;
+       struct qtnf_tx_bd *txbd;
+       unsigned long flags;
+       int len, i;
+       u32 info;
+       int ret = 0;
+
+       spin_lock_irqsave(&priv->tx0_lock, flags);
+
+       if (!qtnf_tx_queue_ready(priv)) {
+               if (skb->dev) {
+                       netif_tx_stop_all_queues(skb->dev);
+                       priv->tx_stopped = 1;
+               }
+
+               spin_unlock_irqrestore(&priv->tx0_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       i = priv->tx_bd_w_index;
+       priv->tx_skb[i] = skb;
+       len = skb->len;
+
+       skb_paddr = pci_map_single(priv->pdev, skb->data,
+                                  skb->len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(priv->pdev, skb_paddr)) {
+               pr_err("skb DMA mapping error: %pad\n", &skb_paddr);
+               ret = -ENOMEM;
+               goto tx_done;
+       }
+
+       txbd = &priv->tx_bd_vbase[i];
+       txbd->addr = cpu_to_le32(QTN_HOST_LO32(skb_paddr));
+       txbd->addr_h = cpu_to_le32(QTN_HOST_HI32(skb_paddr));
+
+       info = (len & QTN_PCIE_TX_DESC_LEN_MASK) << QTN_PCIE_TX_DESC_LEN_SHIFT;
+       txbd->info = cpu_to_le32(info);
+
+       /* sync up all descriptor updates before passing them to EP */
+       dma_wmb();
+
+       /* write new TX descriptor to PCIE_RX_FIFO on EP */
+       txbd_paddr = priv->tx_bd_pbase + i * sizeof(struct qtnf_tx_bd);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       writel(QTN_HOST_HI32(txbd_paddr),
+              PCIE_HDP_HOST_WR_DESC0_H(priv->pcie_reg_base));
+#endif
+       writel(QTN_HOST_LO32(txbd_paddr),
+              PCIE_HDP_HOST_WR_DESC0(priv->pcie_reg_base));
+
+       if (++i >= priv->tx_bd_num)
+               i = 0;
+
+       priv->tx_bd_w_index = i;
+
+tx_done:
+       if (ret && skb) {
+               pr_err_ratelimited("drop skb\n");
+               if (skb->dev)
+                       skb->dev->stats.tx_dropped++;
+               dev_kfree_skb_any(skb);
+       }
+
+       priv->tx_done_count++;
+       spin_unlock_irqrestore(&priv->tx0_lock, flags);
+
+       qtnf_pcie_data_tx_reclaim(priv);
+
+       return NETDEV_TX_OK;
+}
+
+static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       int ret;
+
+       ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len);
+
+       if (ret == -ETIMEDOUT) {
+               pr_err("EP firmware is dead\n");
+               bus->fw_state = QTNF_FW_STATE_EP_DEAD;
+       }
+
+       return ret;
+}
+
+static irqreturn_t qtnf_interrupt(int irq, void *data)
+{
+       struct qtnf_bus *bus = (struct qtnf_bus *)data;
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       u32 status;
+
+       priv->pcie_irq_count++;
+       status = readl(PCIE_HDP_INT_STATUS(priv->pcie_reg_base));
+
+       qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_in);
+       qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_out);
+
+       if (!(status & priv->pcie_irq_mask))
+               goto irq_done;
+
+       if (status & PCIE_HDP_INT_RX_BITS)
+               priv->pcie_irq_rx_count++;
+
+       if (status & PCIE_HDP_INT_TX_BITS)
+               priv->pcie_irq_tx_count++;
+
+       if (status & PCIE_HDP_INT_HHBM_UF)
+               priv->pcie_irq_uf_count++;
+
+       if (status & PCIE_HDP_INT_RX_BITS) {
+               qtnf_dis_rxdone_irq(priv);
+               napi_schedule(&bus->mux_napi);
+       }
+
+       if (status & PCIE_HDP_INT_TX_BITS) {
+               qtnf_dis_txdone_irq(priv);
+               tasklet_hi_schedule(&priv->reclaim_tq);
+       }
+
+irq_done:
+       /* H/W workaround: clean all bits, not only enabled */
+       qtnf_non_posted_write(~0U, PCIE_HDP_INT_STATUS(priv->pcie_reg_base));
+
+       if (!priv->msi_enabled)
+               qtnf_deassert_intx(priv);
+
+       return IRQ_HANDLED;
+}
+
+static int qtnf_rx_data_ready(struct qtnf_pcie_bus_priv *priv)
+{
+       u16 index = priv->rx_bd_r_index;
+       struct qtnf_rx_bd *rxbd;
+       u32 descw;
+
+       rxbd = &priv->rx_bd_vbase[index];
+       descw = le32_to_cpu(rxbd->info);
+
+       if (descw & QTN_TXDONE_MASK)
+               return 1;
+
+       return 0;
+}
+
+static int qtnf_rx_poll(struct napi_struct *napi, int budget)
+{
+       struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi);
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       struct net_device *ndev = NULL;
+       struct sk_buff *skb = NULL;
+       int processed = 0;
+       struct qtnf_rx_bd *rxbd;
+       dma_addr_t skb_paddr;
+       int consume;
+       u32 descw;
+       u32 psize;
+       u16 r_idx;
+       u16 w_idx;
+       int ret;
+
+       while (processed < budget) {
+
+
+               if (!qtnf_rx_data_ready(priv))
+                       goto rx_out;
+
+               r_idx = priv->rx_bd_r_index;
+               rxbd = &priv->rx_bd_vbase[r_idx];
+               descw = le32_to_cpu(rxbd->info);
+
+               skb = priv->rx_skb[r_idx];
+               psize = QTN_GET_LEN(descw);
+               consume = 1;
+
+               if (!(descw & QTN_TXDONE_MASK)) {
+                       pr_warn("skip invalid rxbd[%d]\n", r_idx);
+                       consume = 0;
+               }
+
+               if (!skb) {
+                       pr_warn("skip missing rx_skb[%d]\n", r_idx);
+                       consume = 0;
+               }
+
+               if (skb && (skb_tailroom(skb) <  psize)) {
+                       pr_err("skip packet with invalid length: %u > %u\n",
+                              psize, skb_tailroom(skb));
+                       consume = 0;
+               }
+
+               if (skb) {
+                       skb_paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h),
+                                                 le32_to_cpu(rxbd->addr));
+                       pci_unmap_single(priv->pdev, skb_paddr, SKB_BUF_SIZE,
+                                        PCI_DMA_FROMDEVICE);
+               }
+
+               if (consume) {
+                       skb_put(skb, psize);
+                       ndev = qtnf_classify_skb(bus, skb);
+                       if (likely(ndev)) {
+                               qtnf_update_rx_stats(ndev, skb);
+                               skb->protocol = eth_type_trans(skb, ndev);
+                               napi_gro_receive(napi, skb);
+                       } else {
+                               pr_debug("drop untagged skb\n");
+                               bus->mux_dev.stats.rx_dropped++;
+                               dev_kfree_skb_any(skb);
+                       }
+               } else {
+                       if (skb) {
+                               bus->mux_dev.stats.rx_dropped++;
+                               dev_kfree_skb_any(skb);
+                       }
+               }
+
+               priv->rx_skb[r_idx] = NULL;
+               if (++r_idx >= priv->rx_bd_num)
+                       r_idx = 0;
+
+               priv->rx_bd_r_index = r_idx;
+
+               /* repalce processed buffer by a new one */
+               w_idx = priv->rx_bd_w_index;
+               while (CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
+                                 priv->rx_bd_num) > 0) {
+                       if (++w_idx >= priv->rx_bd_num)
+                               w_idx = 0;
+
+                       ret = skb2rbd_attach(priv, w_idx);
+                       if (ret) {
+                               pr_err("failed to allocate new rx_skb[%d]\n",
+                                      w_idx);
+                               break;
+                       }
+               }
+
+               processed++;
+       }
+
+rx_out:
+       if (processed < budget) {
+               napi_complete(napi);
+               qtnf_en_rxdone_irq(priv);
+       }
+
+       return processed;
+}
+
+static void
+qtnf_pcie_data_tx_timeout(struct qtnf_bus *bus, struct net_device *ndev)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+
+       tasklet_hi_schedule(&priv->reclaim_tq);
+}
+
+static void qtnf_pcie_data_rx_start(struct qtnf_bus *bus)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+
+       qtnf_enable_hdp_irqs(priv);
+       napi_enable(&bus->mux_napi);
+}
+
+static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+
+       napi_disable(&bus->mux_napi);
+       qtnf_disable_hdp_irqs(priv);
+}
+
+static const struct qtnf_bus_ops qtnf_pcie_bus_ops = {
+       /* control path methods */
+       .control_tx     = qtnf_pcie_control_tx,
+
+       /* data path methods */
+       .data_tx                = qtnf_pcie_data_tx,
+       .data_tx_timeout        = qtnf_pcie_data_tx_timeout,
+       .data_rx_start          = qtnf_pcie_data_rx_start,
+       .data_rx_stop           = qtnf_pcie_data_rx_stop,
+};
+
+static int qtnf_dbg_mps_show(struct seq_file *s, void *data)
+{
+       struct qtnf_bus *bus = dev_get_drvdata(s->private);
+       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+
+       seq_printf(s, "%d\n", priv->mps);
+
+       return 0;
+}
+
+static int qtnf_dbg_msi_show(struct seq_file *s, void *data)
+{
+       struct qtnf_bus *bus = dev_get_drvdata(s->private);
+       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+
+       seq_printf(s, "%u\n", priv->msi_enabled);
+
+       return 0;
+}
+
+static int qtnf_dbg_irq_stats(struct seq_file *s, void *data)
+{
+       struct qtnf_bus *bus = dev_get_drvdata(s->private);
+       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+       u32 reg = readl(PCIE_HDP_INT_EN(priv->pcie_reg_base));
+       u32 status;
+
+       seq_printf(s, "pcie_irq_count(%u)\n", priv->pcie_irq_count);
+       seq_printf(s, "pcie_irq_tx_count(%u)\n", priv->pcie_irq_tx_count);
+       status = reg &  PCIE_HDP_INT_TX_BITS;
+       seq_printf(s, "pcie_irq_tx_status(%s)\n",
+                  (status == PCIE_HDP_INT_TX_BITS) ? "EN" : "DIS");
+       seq_printf(s, "pcie_irq_rx_count(%u)\n", priv->pcie_irq_rx_count);
+       status = reg &  PCIE_HDP_INT_RX_BITS;
+       seq_printf(s, "pcie_irq_rx_status(%s)\n",
+                  (status == PCIE_HDP_INT_RX_BITS) ? "EN" : "DIS");
+       seq_printf(s, "pcie_irq_uf_count(%u)\n", priv->pcie_irq_uf_count);
+       status = reg &  PCIE_HDP_INT_HHBM_UF;
+       seq_printf(s, "pcie_irq_hhbm_uf_status(%s)\n",
+                  (status == PCIE_HDP_INT_HHBM_UF) ? "EN" : "DIS");
+
+       return 0;
+}
+
+static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data)
+{
+       struct qtnf_bus *bus = dev_get_drvdata(s->private);
+       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+
+       seq_printf(s, "tx_full_count(%u)\n", priv->tx_full_count);
+       seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count);
+       seq_printf(s, "tx_reclaim_done(%u)\n", priv->tx_reclaim_done);
+       seq_printf(s, "tx_reclaim_req(%u)\n", priv->tx_reclaim_req);
+
+       seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index);
+       seq_printf(s, "tx_bd_p_index(%u)\n",
+                  readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
+                       & (priv->tx_bd_num - 1));
+       seq_printf(s, "tx_bd_w_index(%u)\n", priv->tx_bd_w_index);
+       seq_printf(s, "tx queue len(%u)\n",
+                  CIRC_CNT(priv->tx_bd_w_index, priv->tx_bd_r_index,
+                           priv->tx_bd_num));
+
+       seq_printf(s, "rx_bd_r_index(%u)\n", priv->rx_bd_r_index);
+       seq_printf(s, "rx_bd_p_index(%u)\n",
+                  readl(PCIE_HDP_TX0DMA_CNT(priv->pcie_reg_base))
+                       & (priv->rx_bd_num - 1));
+       seq_printf(s, "rx_bd_w_index(%u)\n", priv->rx_bd_w_index);
+       seq_printf(s, "rx alloc queue len(%u)\n",
+                  CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
+                             priv->rx_bd_num));
+
+       return 0;
+}
+
+static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
+{
+       struct qtnf_bus *bus = dev_get_drvdata(s->private);
+       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+
+       seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n",
+                  priv->shm_ipc_ep_in.tx_packet_count);
+       seq_printf(s, "shm_ipc_ep_in.rx_packet_count(%zu)\n",
+                  priv->shm_ipc_ep_in.rx_packet_count);
+       seq_printf(s, "shm_ipc_ep_out.tx_packet_count(%zu)\n",
+                  priv->shm_ipc_ep_out.tx_timeout_count);
+       seq_printf(s, "shm_ipc_ep_out.rx_packet_count(%zu)\n",
+                  priv->shm_ipc_ep_out.rx_packet_count);
+
+       return 0;
+}
+
+static int qtnf_ep_fw_send(struct qtnf_pcie_bus_priv *priv, uint32_t size,
+                          int blk, const u8 *pblk, const u8 *fw)
+{
+       struct pci_dev *pdev = priv->pdev;
+       struct qtnf_bus *bus = pci_get_drvdata(pdev);
+
+       struct qtnf_pcie_fw_hdr *hdr;
+       u8 *pdata;
+
+       int hds = sizeof(*hdr);
+       struct sk_buff *skb = NULL;
+       int len = 0;
+       int ret;
+
+       skb = __dev_alloc_skb(QTN_PCIE_FW_BUFSZ, GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       skb->len = QTN_PCIE_FW_BUFSZ;
+       skb->dev = NULL;
+
+       hdr = (struct qtnf_pcie_fw_hdr *)skb->data;
+       memcpy(hdr->boardflg, QTN_PCIE_BOARDFLG, strlen(QTN_PCIE_BOARDFLG));
+       hdr->fwsize = cpu_to_le32(size);
+       hdr->seqnum = cpu_to_le32(blk);
+
+       if (blk)
+               hdr->type = cpu_to_le32(QTN_FW_DSUB);
+       else
+               hdr->type = cpu_to_le32(QTN_FW_DBEGIN);
+
+       pdata = skb->data + hds;
+
+       len = QTN_PCIE_FW_BUFSZ - hds;
+       if (pblk >= (fw + size - len)) {
+               len = fw + size - pblk;
+               hdr->type = cpu_to_le32(QTN_FW_DEND);
+       }
+
+       hdr->pktlen = cpu_to_le32(len);
+       memcpy(pdata, pblk, len);
+       hdr->crc = cpu_to_le32(~crc32(0, pdata, len));
+
+       ret = qtnf_pcie_data_tx(bus, skb);
+
+       return (ret == NETDEV_TX_OK) ? len : 0;
+}
+
+static int
+qtnf_ep_fw_load(struct qtnf_pcie_bus_priv *priv, const u8 *fw, u32 fw_size)
+{
+       int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pcie_fw_hdr);
+       int blk_count = fw_size / blk_size + ((fw_size % blk_size) ? 1 : 0);
+       const u8 *pblk = fw;
+       int threshold = 0;
+       int blk = 0;
+       int len;
+
+       pr_debug("FW upload started: fw_addr=0x%p size=%d\n", fw, fw_size);
+
+       while (blk < blk_count) {
+               if (++threshold > 10000) {
+                       pr_err("FW upload failed: too many retries\n");
+                       return -ETIMEDOUT;
+               }
+
+               len = qtnf_ep_fw_send(priv, fw_size, blk, pblk, fw);
+               if (len <= 0)
+                       continue;
+
+               if (!((blk + 1) & QTN_PCIE_FW_DLMASK) ||
+                   (blk == (blk_count - 1))) {
+                       qtnf_set_state(&priv->bda->bda_rc_state,
+                                      QTN_RC_FW_SYNC);
+                       if (qtnf_poll_state(&priv->bda->bda_ep_state,
+                                           QTN_EP_FW_SYNC,
+                                           QTN_FW_DL_TIMEOUT_MS)) {
+                               pr_err("FW upload failed: SYNC timed out\n");
+                               return -ETIMEDOUT;
+                       }
+
+                       qtnf_clear_state(&priv->bda->bda_ep_state,
+                                        QTN_EP_FW_SYNC);
+
+                       if (qtnf_is_state(&priv->bda->bda_ep_state,
+                                         QTN_EP_FW_RETRY)) {
+                               if (blk == (blk_count - 1)) {
+                                       int last_round =
+                                               blk_count & QTN_PCIE_FW_DLMASK;
+                                       blk -= last_round;
+                                       pblk -= ((last_round - 1) *
+                                               blk_size + len);
+                               } else {
+                                       blk -= QTN_PCIE_FW_DLMASK;
+                                       pblk -= QTN_PCIE_FW_DLMASK * blk_size;
+                               }
+
+                               qtnf_clear_state(&priv->bda->bda_ep_state,
+                                                QTN_EP_FW_RETRY);
+
+                               pr_warn("FW upload retry: block #%d\n", blk);
+                               continue;
+                       }
+
+                       qtnf_pcie_data_tx_reclaim(priv);
+               }
+
+               pblk += len;
+               blk++;
+       }
+
+       pr_debug("FW upload completed: totally sent %d blocks\n", blk);
+       return 0;
+}
+
+static void qtnf_fw_work_handler(struct work_struct *work)
+{
+       struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work);
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       struct pci_dev *pdev = priv->pdev;
+       const struct firmware *fw;
+       int ret;
+       u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK;
+       const char *fwname = QTN_PCI_PEARL_FW_NAME;
+
+       if (flashboot) {
+               state |= QTN_RC_FW_FLASHBOOT;
+       } else {
+               ret = request_firmware(&fw, fwname, &pdev->dev);
+               if (ret < 0) {
+                       pr_err("failed to get firmware %s\n", fwname);
+                       goto fw_load_fail;
+               }
+       }
+
+       qtnf_set_state(&priv->bda->bda_rc_state, state);
+
+       if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY,
+                           QTN_FW_DL_TIMEOUT_MS)) {
+               pr_err("card is not ready\n");
+
+               if (!flashboot)
+                       release_firmware(fw);
+
+               goto fw_load_fail;
+       }
+
+       qtnf_clear_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY);
+
+       if (flashboot) {
+               pr_info("booting firmware from flash\n");
+       } else {
+               pr_info("starting firmware upload: %s\n", fwname);
+
+               ret = qtnf_ep_fw_load(priv, fw->data, fw->size);
+               release_firmware(fw);
+               if (ret) {
+                       pr_err("firmware upload error\n");
+                       goto fw_load_fail;
+               }
+       }
+
+       if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_DONE,
+                           QTN_FW_DL_TIMEOUT_MS)) {
+               pr_err("firmware bringup timed out\n");
+               goto fw_load_fail;
+       }
+
+       bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE;
+       pr_info("firmware is up and running\n");
+
+       if (qtnf_poll_state(&priv->bda->bda_ep_state,
+                           QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) {
+               pr_err("firmware runtime failure\n");
+               goto fw_load_fail;
+       }
+
+       ret = qtnf_core_attach(bus);
+       if (ret) {
+               pr_err("failed to attach core\n");
+               goto fw_load_fail;
+       }
+
+       qtnf_debugfs_init(bus, DRV_NAME);
+       qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show);
+       qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show);
+       qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats);
+       qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);
+       qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats);
+
+       goto fw_load_exit;
+
+fw_load_fail:
+       bus->fw_state = QTNF_FW_STATE_DETACHED;
+
+fw_load_exit:
+       complete(&bus->firmware_init_complete);
+       put_device(&pdev->dev);
+}
+
+static void qtnf_bringup_fw_async(struct qtnf_bus *bus)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
+       struct pci_dev *pdev = priv->pdev;
+
+       get_device(&pdev->dev);
+       INIT_WORK(&bus->fw_work, qtnf_fw_work_handler);
+       schedule_work(&bus->fw_work);
+}
+
+static void qtnf_reclaim_tasklet_fn(unsigned long data)
+{
+       struct qtnf_pcie_bus_priv *priv = (void *)data;
+
+       qtnf_pcie_data_tx_reclaim(priv);
+       qtnf_en_txdone_irq(priv);
+}
+
+static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       struct qtnf_pcie_bus_priv *pcie_priv;
+       struct qtnf_bus *bus;
+       int ret;
+
+       bus = devm_kzalloc(&pdev->dev,
+                          sizeof(*bus) + sizeof(*pcie_priv), GFP_KERNEL);
+       if (!bus)
+               return -ENOMEM;
+
+       pcie_priv = get_bus_priv(bus);
+
+       pci_set_drvdata(pdev, bus);
+       bus->bus_ops = &qtnf_pcie_bus_ops;
+       bus->dev = &pdev->dev;
+       bus->fw_state = QTNF_FW_STATE_RESET;
+       pcie_priv->pdev = pdev;
+
+       init_completion(&bus->firmware_init_complete);
+       mutex_init(&bus->bus_lock);
+       spin_lock_init(&pcie_priv->tx0_lock);
+       spin_lock_init(&pcie_priv->irq_lock);
+       spin_lock_init(&pcie_priv->tx_reclaim_lock);
+
+       /* init stats */
+       pcie_priv->tx_full_count = 0;
+       pcie_priv->tx_done_count = 0;
+       pcie_priv->pcie_irq_count = 0;
+       pcie_priv->pcie_irq_rx_count = 0;
+       pcie_priv->pcie_irq_tx_count = 0;
+       pcie_priv->pcie_irq_uf_count = 0;
+       pcie_priv->tx_reclaim_done = 0;
+       pcie_priv->tx_reclaim_req = 0;
+
+       tasklet_init(&pcie_priv->reclaim_tq, qtnf_reclaim_tasklet_fn,
+                    (unsigned long)pcie_priv);
+
+       init_dummy_netdev(&bus->mux_dev);
+       netif_napi_add(&bus->mux_dev, &bus->mux_napi,
+                      qtnf_rx_poll, 10);
+
+       pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE");
+       if (!pcie_priv->workqueue) {
+               pr_err("failed to alloc bus workqueue\n");
+               ret = -ENODEV;
+               goto err_init;
+       }
+
+       if (!pci_is_pcie(pdev)) {
+               pr_err("device %s is not PCI Express\n", pci_name(pdev));
+               ret = -EIO;
+               goto err_base;
+       }
+
+       qtnf_tune_pcie_mps(pcie_priv);
+
+       ret = pcim_enable_device(pdev);
+       if (ret) {
+               pr_err("failed to init PCI device %x\n", pdev->device);
+               goto err_base;
+       } else {
+               pr_debug("successful init of PCI device %x\n", pdev->device);
+       }
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+#else
+       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+#endif
+       if (ret) {
+               pr_err("PCIE DMA coherent mask init failed\n");
+               goto err_base;
+       }
+
+       pci_set_master(pdev);
+       qtnf_pcie_init_irq(pcie_priv);
+
+       ret = qtnf_pcie_init_memory(pcie_priv);
+       if (ret < 0) {
+               pr_err("PCIE memory init failed\n");
+               goto err_base;
+       }
+
+       pci_save_state(pdev);
+
+       ret = qtnf_pcie_init_shm_ipc(pcie_priv);
+       if (ret < 0) {
+               pr_err("PCIE SHM IPC init failed\n");
+               goto err_base;
+       }
+
+       ret = qtnf_pcie_init_xfer(pcie_priv);
+       if (ret) {
+               pr_err("PCIE xfer init failed\n");
+               goto err_ipc;
+       }
+
+       /* init default irq settings */
+       qtnf_init_hdp_irqs(pcie_priv);
+
+       /* start with disabled irqs */
+       qtnf_disable_hdp_irqs(pcie_priv);
+
+       ret = devm_request_irq(&pdev->dev, pdev->irq, &qtnf_interrupt, 0,
+                              "qtnf_pcie_irq", (void *)bus);
+       if (ret) {
+               pr_err("failed to request pcie irq %d\n", pdev->irq);
+               goto err_xfer;
+       }
+
+       qtnf_bringup_fw_async(bus);
+
+       return 0;
+
+err_xfer:
+       qtnf_free_xfer_buffers(pcie_priv);
+
+err_ipc:
+       qtnf_pcie_free_shm_ipc(pcie_priv);
+
+err_base:
+       flush_workqueue(pcie_priv->workqueue);
+       destroy_workqueue(pcie_priv->workqueue);
+       netif_napi_del(&bus->mux_napi);
+
+err_init:
+       tasklet_kill(&pcie_priv->reclaim_tq);
+       pci_set_drvdata(pdev, NULL);
+
+       return ret;
+}
+
+static void qtnf_pcie_remove(struct pci_dev *pdev)
+{
+       struct qtnf_pcie_bus_priv *priv;
+       struct qtnf_bus *bus;
+
+       bus = pci_get_drvdata(pdev);
+       if (!bus)
+               return;
+
+       wait_for_completion(&bus->firmware_init_complete);
+
+       if (bus->fw_state == QTNF_FW_STATE_ACTIVE ||
+           bus->fw_state == QTNF_FW_STATE_EP_DEAD)
+               qtnf_core_detach(bus);
+
+       priv = get_bus_priv(bus);
+
+       netif_napi_del(&bus->mux_napi);
+       flush_workqueue(priv->workqueue);
+       destroy_workqueue(priv->workqueue);
+       tasklet_kill(&priv->reclaim_tq);
+
+       qtnf_free_xfer_buffers(priv);
+       qtnf_debugfs_remove(bus);
+
+       qtnf_pcie_free_shm_ipc(priv);
+       qtnf_reset_card(priv);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int qtnf_pcie_suspend(struct device *dev)
+{
+       return -EOPNOTSUPP;
+}
+
+static int qtnf_pcie_resume(struct device *dev)
+{
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_SLEEP
+/* Power Management Hooks */
+static SIMPLE_DEV_PM_OPS(qtnf_pcie_pm_ops, qtnf_pcie_suspend,
+                        qtnf_pcie_resume);
+#endif
+
+static const struct pci_device_id qtnf_pcie_devid_table[] = {
+       {
+               PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QTN_PEARL,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+       },
+       { },
+};
+
+MODULE_DEVICE_TABLE(pci, qtnf_pcie_devid_table);
+
+static struct pci_driver qtnf_pcie_drv_data = {
+       .name = DRV_NAME,
+       .id_table = qtnf_pcie_devid_table,
+       .probe = qtnf_pcie_probe,
+       .remove = qtnf_pcie_remove,
+#ifdef CONFIG_PM_SLEEP
+       .driver = {
+               .pm = &qtnf_pcie_pm_ops,
+       },
+#endif
+};
+
+static int __init qtnf_pcie_register(void)
+{
+       pr_info("register Quantenna QSR10g FullMAC PCIE driver\n");
+       return pci_register_driver(&qtnf_pcie_drv_data);
+}
+
+static void __exit qtnf_pcie_exit(void)
+{
+       pr_info("unregister Quantenna QSR10g FullMAC PCIE driver\n");
+       pci_unregister_driver(&qtnf_pcie_drv_data);
+}
+
+module_init(qtnf_pcie_register);
+module_exit(qtnf_pcie_exit);
+
+MODULE_AUTHOR("Quantenna Communications");
+MODULE_DESCRIPTION("Quantenna QSR10g PCIe bus driver for 802.11 wireless LAN.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h
new file mode 100644 (file)
index 0000000..986b957
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015-2016 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _QTN_FMAC_PCIE_H_
+#define _QTN_FMAC_PCIE_H_
+
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include "pearl_pcie_regs.h"
+#include "pearl_pcie_ipc.h"
+#include "shm_ipc.h"
+
+struct bus;
+
+struct qtnf_pcie_bus_priv {
+       struct pci_dev  *pdev;
+
+       /* lock for irq configuration changes */
+       spinlock_t irq_lock;
+
+       /* lock for tx reclaim operations */
+       spinlock_t tx_reclaim_lock;
+       /* lock for tx0 operations */
+       spinlock_t tx0_lock;
+       u8 msi_enabled;
+       u8 tx_stopped;
+       int mps;
+
+       struct workqueue_struct *workqueue;
+       struct tasklet_struct reclaim_tq;
+
+       void __iomem *sysctl_bar;
+       void __iomem *epmem_bar;
+       void __iomem *dmareg_bar;
+
+       struct qtnf_shm_ipc shm_ipc_ep_in;
+       struct qtnf_shm_ipc shm_ipc_ep_out;
+
+       struct qtnf_pcie_bda __iomem *bda;
+       void __iomem *pcie_reg_base;
+
+       u16 tx_bd_num;
+       u16 rx_bd_num;
+
+       struct sk_buff **tx_skb;
+       struct sk_buff **rx_skb;
+
+       struct qtnf_tx_bd *tx_bd_vbase;
+       dma_addr_t tx_bd_pbase;
+
+       struct qtnf_rx_bd *rx_bd_vbase;
+       dma_addr_t rx_bd_pbase;
+
+       dma_addr_t bd_table_paddr;
+       void *bd_table_vaddr;
+       u32 bd_table_len;
+
+       u32 rx_bd_w_index;
+       u32 rx_bd_r_index;
+
+       u32 tx_bd_w_index;
+       u32 tx_bd_r_index;
+
+       u32 pcie_irq_mask;
+
+       /* diagnostics stats */
+       u32 pcie_irq_count;
+       u32 pcie_irq_rx_count;
+       u32 pcie_irq_tx_count;
+       u32 pcie_irq_uf_count;
+       u32 tx_full_count;
+       u32 tx_done_count;
+       u32 tx_reclaim_done;
+       u32 tx_reclaim_req;
+};
+
+#endif /* _QTN_FMAC_PCIE_H_ */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h
new file mode 100644 (file)
index 0000000..00bb21a
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015-2016 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _QTN_FMAC_PCIE_IPC_H_
+#define _QTN_FMAC_PCIE_IPC_H_
+
+#include <linux/types.h>
+
+#include "shm_ipc_defs.h"
+
+/* bitmap for EP status and flags: updated by EP, read by RC */
+#define QTN_EP_HAS_UBOOT       BIT(0)
+#define QTN_EP_HAS_FIRMWARE    BIT(1)
+#define QTN_EP_REQ_UBOOT       BIT(2)
+#define QTN_EP_REQ_FIRMWARE    BIT(3)
+#define QTN_EP_ERROR_UBOOT     BIT(4)
+#define QTN_EP_ERROR_FIRMWARE  BIT(5)
+
+#define QTN_EP_FW_LOADRDY      BIT(8)
+#define QTN_EP_FW_SYNC         BIT(9)
+#define QTN_EP_FW_RETRY                BIT(10)
+#define QTN_EP_FW_QLINK_DONE   BIT(15)
+#define QTN_EP_FW_DONE         BIT(16)
+
+/* bitmap for RC status and flags: updated by RC, read by EP */
+#define QTN_RC_PCIE_LINK       BIT(0)
+#define QTN_RC_NET_LINK                BIT(1)
+#define QTN_RC_FW_FLASHBOOT    BIT(5)
+#define QTN_RC_FW_QLINK                BIT(7)
+#define QTN_RC_FW_LOADRDY      BIT(8)
+#define QTN_RC_FW_SYNC         BIT(9)
+
+/* state transition timeouts */
+#define QTN_FW_DL_TIMEOUT_MS   3000
+#define QTN_FW_QLINK_TIMEOUT_MS        30000
+#define QTN_EP_RESET_WAIT_MS   1000
+
+#define PCIE_HDP_INT_RX_BITS (0                \
+       | PCIE_HDP_INT_EP_TXDMA         \
+       | PCIE_HDP_INT_EP_TXEMPTY       \
+       | PCIE_HDP_INT_HHBM_UF          \
+       )
+
+#define PCIE_HDP_INT_TX_BITS (0                \
+       | PCIE_HDP_INT_EP_RXDMA         \
+       )
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+#define QTN_HOST_HI32(a)       ((u32)(((u64)a) >> 32))
+#define QTN_HOST_LO32(a)       ((u32)(((u64)a) & 0xffffffffUL))
+#define QTN_HOST_ADDR(h, l)    ((((u64)h) << 32) | ((u64)l))
+#else
+#define QTN_HOST_HI32(a)       0
+#define QTN_HOST_LO32(a)       ((u32)(((u32)a) & 0xffffffffUL))
+#define QTN_HOST_ADDR(h, l)    ((u32)l)
+#endif
+
+#define QTN_SYSCTL_BAR 0
+#define QTN_SHMEM_BAR  2
+#define QTN_DMA_BAR    3
+
+#define QTN_PCIE_BDA_VERSION           0x1002
+
+#define PCIE_BDA_NAMELEN               32
+#define PCIE_HHBM_MAX_SIZE             2048
+
+#define SKB_BUF_SIZE           2048
+
+#define QTN_PCIE_BOARDFLG      "PCIEQTN"
+#define QTN_PCIE_FW_DLMASK     0xF
+#define QTN_PCIE_FW_BUFSZ      2048
+
+#define QTN_ENET_ADDR_LENGTH   6
+
+#define QTN_TXDONE_MASK                ((u32)0x80000000)
+#define QTN_GET_LEN(x)         ((x) & 0xFFFF)
+
+#define QTN_PCIE_TX_DESC_LEN_MASK      0xFFFF
+#define QTN_PCIE_TX_DESC_LEN_SHIFT     0
+#define QTN_PCIE_TX_DESC_PORT_MASK     0xF
+#define QTN_PCIE_TX_DESC_PORT_SHIFT    16
+#define QTN_PCIE_TX_DESC_TQE_BIT       BIT(24)
+
+#define QTN_EP_LHOST_TQE_PORT  4
+
+enum qtnf_pcie_bda_ipc_flags {
+       QTN_PCIE_IPC_FLAG_HBM_MAGIC     = BIT(0),
+       QTN_PCIE_IPC_FLAG_SHM_PIO       = BIT(1),
+};
+
+struct qtnf_pcie_bda {
+       __le16 bda_len;
+       __le16 bda_version;
+       __le32 bda_pci_endian;
+       __le32 bda_ep_state;
+       __le32 bda_rc_state;
+       __le32 bda_dma_mask;
+       __le32 bda_msi_addr;
+       __le32 bda_flashsz;
+       u8 bda_boardname[PCIE_BDA_NAMELEN];
+       __le32 bda_rc_msi_enabled;
+       u8 bda_hhbm_list[PCIE_HHBM_MAX_SIZE];
+       __le32 bda_dsbw_start_index;
+       __le32 bda_dsbw_end_index;
+       __le32 bda_dsbw_total_bytes;
+       __le32 bda_rc_tx_bd_base;
+       __le32 bda_rc_tx_bd_num;
+       u8 bda_pcie_mac[QTN_ENET_ADDR_LENGTH];
+       struct qtnf_shm_ipc_region bda_shm_reg1 __aligned(4096); /* host TX */
+       struct qtnf_shm_ipc_region bda_shm_reg2 __aligned(4096); /* host RX */
+} __packed;
+
+struct qtnf_tx_bd {
+       __le32 addr;
+       __le32 addr_h;
+       __le32 info;
+       __le32 info_h;
+} __packed;
+
+struct qtnf_rx_bd {
+       __le32 addr;
+       __le32 addr_h;
+       __le32 info;
+       __le32 info_h;
+       __le32 next_ptr;
+       __le32 next_ptr_h;
+} __packed;
+
+enum qtnf_fw_loadtype {
+       QTN_FW_DBEGIN,
+       QTN_FW_DSUB,
+       QTN_FW_DEND,
+       QTN_FW_CTRL
+};
+
+struct qtnf_pcie_fw_hdr {
+       u8 boardflg[8];
+       __le32 fwsize;
+       __le32 seqnum;
+       __le32 type;
+       __le32 pktlen;
+       __le32 crc;
+} __packed;
+
+#endif /* _QTN_FMAC_PCIE_IPC_H_ */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h
new file mode 100644 (file)
index 0000000..0bfe285
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2015 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __PEARL_PCIE_H
+#define __PEARL_PCIE_H
+
+#define        PCIE_GEN2_BASE                          (0xe9000000)
+#define        PCIE_GEN3_BASE                          (0xe7000000)
+
+#define PEARL_CUR_PCIE_BASE                    (PCIE_GEN2_BASE)
+#define PCIE_HDP_OFFSET                                (0x2000)
+
+#define PCIE_HDP_CTRL(base)                    ((base) + 0x2c00)
+#define PCIE_HDP_AXI_CTRL(base)                        ((base) + 0x2c04)
+#define PCIE_HDP_HOST_WR_DESC0(base)           ((base) + 0x2c10)
+#define PCIE_HDP_HOST_WR_DESC0_H(base)         ((base) + 0x2c14)
+#define PCIE_HDP_HOST_WR_DESC1(base)           ((base) + 0x2c18)
+#define PCIE_HDP_HOST_WR_DESC1_H(base)         ((base) + 0x2c1c)
+#define PCIE_HDP_HOST_WR_DESC2(base)           ((base) + 0x2c20)
+#define PCIE_HDP_HOST_WR_DESC2_H(base)         ((base) + 0x2c24)
+#define PCIE_HDP_HOST_WR_DESC3(base)           ((base) + 0x2c28)
+#define PCIE_HDP_HOST_WR_DESC4_H(base)         ((base) + 0x2c2c)
+#define PCIE_HDP_RX_INT_CTRL(base)             ((base) + 0x2c30)
+#define PCIE_HDP_TX_INT_CTRL(base)             ((base) + 0x2c34)
+#define PCIE_HDP_INT_STATUS(base)              ((base) + 0x2c38)
+#define PCIE_HDP_INT_EN(base)                  ((base) + 0x2c3c)
+#define PCIE_HDP_RX_DESC0_PTR(base)            ((base) + 0x2c40)
+#define PCIE_HDP_RX_DESC0_NOE(base)            ((base) + 0x2c44)
+#define PCIE_HDP_RX_DESC1_PTR(base)            ((base) + 0x2c48)
+#define PCIE_HDP_RX_DESC1_NOE(base)            ((base) + 0x2c4c)
+#define PCIE_HDP_RX_DESC2_PTR(base)            ((base) + 0x2c50)
+#define PCIE_HDP_RX_DESC2_NOE(base)            ((base) + 0x2c54)
+#define PCIE_HDP_RX_DESC3_PTR(base)            ((base) + 0x2c58)
+#define PCIE_HDP_RX_DESC3_NOE(base)            ((base) + 0x2c5c)
+
+#define PCIE_HDP_TX0_BASE_ADDR(base)           ((base) + 0x2c60)
+#define PCIE_HDP_TX1_BASE_ADDR(base)           ((base) + 0x2c64)
+#define PCIE_HDP_TX0_Q_CTRL(base)              ((base) + 0x2c70)
+#define PCIE_HDP_TX1_Q_CTRL(base)              ((base) + 0x2c74)
+#define PCIE_HDP_CFG0(base)                    ((base) + 0x2c80)
+#define PCIE_HDP_CFG1(base)                    ((base) + 0x2c84)
+#define PCIE_HDP_CFG2(base)                    ((base) + 0x2c88)
+#define PCIE_HDP_CFG3(base)                    ((base) + 0x2c8c)
+#define PCIE_HDP_CFG4(base)                    ((base) + 0x2c90)
+#define PCIE_HDP_CFG5(base)                    ((base) + 0x2c94)
+#define PCIE_HDP_CFG6(base)                    ((base) + 0x2c98)
+#define PCIE_HDP_CFG7(base)                    ((base) + 0x2c9c)
+#define PCIE_HDP_CFG8(base)                    ((base) + 0x2ca0)
+#define PCIE_HDP_CFG9(base)                    ((base) + 0x2ca4)
+#define PCIE_HDP_CFG10(base)                   ((base) + 0x2ca8)
+#define PCIE_HDP_CFG11(base)                   ((base) + 0x2cac)
+#define PCIE_INT(base)                         ((base) + 0x2cb0)
+#define PCIE_INT_MASK(base)                    ((base) + 0x2cb4)
+#define PCIE_MSI_MASK(base)                    ((base) + 0x2cb8)
+#define PCIE_MSI_PNDG(base)                    ((base) + 0x2cbc)
+#define PCIE_PRI_CFG(base)                     ((base) + 0x2cc0)
+#define PCIE_PHY_CR(base)                      ((base) + 0x2cc4)
+#define PCIE_HDP_CTAG_CTRL(base)               ((base) + 0x2cf4)
+#define PCIE_HDP_HHBM_BUF_PTR(base)            ((base) + 0x2d00)
+#define PCIE_HDP_HHBM_BUF_PTR_H(base)          ((base) + 0x2d04)
+#define PCIE_HDP_HHBM_BUF_FIFO_NOE(base)       ((base) + 0x2d04)
+#define PCIE_HDP_RX0DMA_CNT(base)              ((base) + 0x2d10)
+#define PCIE_HDP_RX1DMA_CNT(base)              ((base) + 0x2d14)
+#define PCIE_HDP_RX2DMA_CNT(base)              ((base) + 0x2d18)
+#define PCIE_HDP_RX3DMA_CNT(base)              ((base) + 0x2d1c)
+#define PCIE_HDP_TX0DMA_CNT(base)              ((base) + 0x2d20)
+#define PCIE_HDP_TX1DMA_CNT(base)              ((base) + 0x2d24)
+#define PCIE_HDP_RXDMA_CTRL(base)              ((base) + 0x2d28)
+#define PCIE_HDP_TX_HOST_Q_SZ_CTRL(base)       ((base) + 0x2d2c)
+#define PCIE_HDP_TX_HOST_Q_BASE_L(base)                ((base) + 0x2d30)
+#define PCIE_HDP_TX_HOST_Q_BASE_H(base)                ((base) + 0x2d34)
+#define PCIE_HDP_TX_HOST_Q_WR_PTR(base)                ((base) + 0x2d38)
+#define PCIE_HDP_TX_HOST_Q_RD_PTR(base)                ((base) + 0x2d3c)
+#define PCIE_HDP_TX_HOST_Q_STS(base)           ((base) + 0x2d40)
+
+/* Host HBM pool registers */
+#define PCIE_HHBM_CSR_REG(base)                        ((base) + 0x2e00)
+#define PCIE_HHBM_Q_BASE_REG(base)             ((base) + 0x2e04)
+#define PCIE_HHBM_Q_LIMIT_REG(base)            ((base) + 0x2e08)
+#define PCIE_HHBM_Q_WR_REG(base)               ((base) + 0x2e0c)
+#define PCIE_HHBM_Q_RD_REG(base)               ((base) + 0x2e10)
+#define PCIE_HHBM_POOL_DATA_0_H(base)          ((base) + 0x2e90)
+#define PCIE_HHBM_CONFIG(base)                 ((base) + 0x2f9c)
+#define PCIE_HHBM_POOL_REQ_0(base)             ((base) + 0x2f10)
+#define PCIE_HHBM_POOL_DATA_0(base)            ((base) + 0x2f40)
+#define PCIE_HHBM_WATERMARK_MASKED_INT(base)   ((base) + 0x2f68)
+#define PCIE_HHBM_WATERMARK_INT(base)          ((base) + 0x2f6c)
+#define PCIE_HHBM_POOL_WATERMARK(base)         ((base) + 0x2f70)
+#define PCIE_HHBM_POOL_OVERFLOW_CNT(base)      ((base) + 0x2f90)
+#define PCIE_HHBM_POOL_UNDERFLOW_CNT(base)     ((base) + 0x2f94)
+#define HBM_INT_STATUS(base)                   ((base) + 0x2f9c)
+#define PCIE_HHBM_POOL_CNFIG(base)             ((base) + 0x2f9c)
+
+/* host HBM bit field definition */
+#define HHBM_CONFIG_SOFT_RESET                 (BIT(8))
+#define HHBM_WR_REQ                            (BIT(0))
+#define HHBM_RD_REQ                            (BIT(1))
+#define HHBM_DONE                              (BIT(31))
+#define HHBM_64BIT                             (BIT(10))
+
+/* offsets for dual PCIE */
+#define PCIE_PORT_LINK_CTL(base)               ((base) + 0x0710)
+#define PCIE_GEN2_CTL(base)                    ((base) + 0x080C)
+#define PCIE_GEN3_OFF(base)                    ((base) + 0x0890)
+#define PCIE_ATU_CTRL1(base)                   ((base) + 0x0904)
+#define PCIE_ATU_CTRL2(base)                   ((base) + 0x0908)
+#define PCIE_ATU_BASE_LOW(base)                        ((base) + 0x090C)
+#define PCIE_ATU_BASE_HIGH(base)               ((base) + 0x0910)
+#define PCIE_ATU_BASE_LIMIT(base)              ((base) + 0x0914)
+#define PCIE_ATU_TGT_LOW(base)                 ((base) + 0x0918)
+#define PCIE_ATU_TGT_HIGH(base)                        ((base) + 0x091C)
+#define PCIE_DMA_WR_ENABLE(base)               ((base) + 0x097C)
+#define PCIE_DMA_WR_CHWTLOW(base)              ((base) + 0x0988)
+#define PCIE_DMA_WR_CHWTHIG(base)              ((base) + 0x098C)
+#define PCIE_DMA_WR_INTSTS(base)               ((base) + 0x09BC)
+#define PCIE_DMA_WR_INTMASK(base)              ((base) + 0x09C4)
+#define PCIE_DMA_WR_INTCLER(base)              ((base) + 0x09C8)
+#define PCIE_DMA_WR_DONE_IMWR_ADDR_L(base)     ((base) + 0x09D0)
+#define PCIE_DMA_WR_DONE_IMWR_ADDR_H(base)     ((base) + 0x09D4)
+#define PCIE_DMA_WR_ABORT_IMWR_ADDR_L(base)    ((base) + 0x09D8)
+#define PCIE_DMA_WR_ABORT_IMWR_ADDR_H(base)    ((base) + 0x09DC)
+#define PCIE_DMA_WR_IMWR_DATA(base)            ((base) + 0x09E0)
+#define PCIE_DMA_WR_LL_ERR_EN(base)            ((base) + 0x0A00)
+#define PCIE_DMA_WR_DOORBELL(base)             ((base) + 0x0980)
+#define PCIE_DMA_RD_ENABLE(base)               ((base) + 0x099C)
+#define PCIE_DMA_RD_DOORBELL(base)             ((base) + 0x09A0)
+#define PCIE_DMA_RD_CHWTLOW(base)              ((base) + 0x09A8)
+#define PCIE_DMA_RD_CHWTHIG(base)              ((base) + 0x09AC)
+#define PCIE_DMA_RD_INTSTS(base)               ((base) + 0x0A10)
+#define PCIE_DMA_RD_INTMASK(base)              ((base) + 0x0A18)
+#define PCIE_DMA_RD_INTCLER(base)              ((base) + 0x0A1C)
+#define PCIE_DMA_RD_ERR_STS_L(base)            ((base) + 0x0A24)
+#define PCIE_DMA_RD_ERR_STS_H(base)            ((base) + 0x0A28)
+#define PCIE_DMA_RD_LL_ERR_EN(base)            ((base) + 0x0A34)
+#define PCIE_DMA_RD_DONE_IMWR_ADDR_L(base)     ((base) + 0x0A3C)
+#define PCIE_DMA_RD_DONE_IMWR_ADDR_H(base)     ((base) + 0x0A40)
+#define PCIE_DMA_RD_ABORT_IMWR_ADDR_L(base)    ((base) + 0x0A44)
+#define PCIE_DMA_RD_ABORT_IMWR_ADDR_H(base)    ((base) + 0x0A48)
+#define PCIE_DMA_RD_IMWR_DATA(base)            ((base) + 0x0A4C)
+#define PCIE_DMA_CHNL_CONTEXT(base)            ((base) + 0x0A6C)
+#define PCIE_DMA_CHNL_CNTRL(base)              ((base) + 0x0A70)
+#define PCIE_DMA_XFR_SIZE(base)                        ((base) + 0x0A78)
+#define PCIE_DMA_SAR_LOW(base)                 ((base) + 0x0A7C)
+#define PCIE_DMA_SAR_HIGH(base)                        ((base) + 0x0A80)
+#define PCIE_DMA_DAR_LOW(base)                 ((base) + 0x0A84)
+#define PCIE_DMA_DAR_HIGH(base)                        ((base) + 0x0A88)
+#define PCIE_DMA_LLPTR_LOW(base)               ((base) + 0x0A8C)
+#define PCIE_DMA_LLPTR_HIGH(base)              ((base) + 0x0A90)
+#define PCIE_DMA_WRLL_ERR_ENB(base)            ((base) + 0x0A00)
+#define PCIE_DMA_RDLL_ERR_ENB(base)            ((base) + 0x0A34)
+#define PCIE_DMABD_CHNL_CNTRL(base)            ((base) + 0x8000)
+#define PCIE_DMABD_XFR_SIZE(base)              ((base) + 0x8004)
+#define PCIE_DMABD_SAR_LOW(base)               ((base) + 0x8008)
+#define PCIE_DMABD_SAR_HIGH(base)              ((base) + 0x800c)
+#define PCIE_DMABD_DAR_LOW(base)               ((base) + 0x8010)
+#define PCIE_DMABD_DAR_HIGH(base)              ((base) + 0x8014)
+#define PCIE_DMABD_LLPTR_LOW(base)             ((base) + 0x8018)
+#define PCIE_DMABD_LLPTR_HIGH(base)            ((base) + 0x801c)
+#define PCIE_WRDMA0_CHNL_CNTRL(base)           ((base) + 0x8000)
+#define PCIE_WRDMA0_XFR_SIZE(base)             ((base) + 0x8004)
+#define PCIE_WRDMA0_SAR_LOW(base)              ((base) + 0x8008)
+#define PCIE_WRDMA0_SAR_HIGH(base)             ((base) + 0x800c)
+#define PCIE_WRDMA0_DAR_LOW(base)              ((base) + 0x8010)
+#define PCIE_WRDMA0_DAR_HIGH(base)             ((base) + 0x8014)
+#define PCIE_WRDMA0_LLPTR_LOW(base)            ((base) + 0x8018)
+#define PCIE_WRDMA0_LLPTR_HIGH(base)           ((base) + 0x801c)
+#define PCIE_WRDMA1_CHNL_CNTRL(base)           ((base) + 0x8020)
+#define PCIE_WRDMA1_XFR_SIZE(base)             ((base) + 0x8024)
+#define PCIE_WRDMA1_SAR_LOW(base)              ((base) + 0x8028)
+#define PCIE_WRDMA1_SAR_HIGH(base)             ((base) + 0x802c)
+#define PCIE_WRDMA1_DAR_LOW(base)              ((base) + 0x8030)
+#define PCIE_WRDMA1_DAR_HIGH(base)             ((base) + 0x8034)
+#define PCIE_WRDMA1_LLPTR_LOW(base)            ((base) + 0x8038)
+#define PCIE_WRDMA1_LLPTR_HIGH(base)           ((base) + 0x803c)
+#define PCIE_RDDMA0_CHNL_CNTRL(base)           ((base) + 0x8040)
+#define PCIE_RDDMA0_XFR_SIZE(base)             ((base) + 0x8044)
+#define PCIE_RDDMA0_SAR_LOW(base)              ((base) + 0x8048)
+#define PCIE_RDDMA0_SAR_HIGH(base)             ((base) + 0x804c)
+#define PCIE_RDDMA0_DAR_LOW(base)              ((base) + 0x8050)
+#define PCIE_RDDMA0_DAR_HIGH(base)             ((base) + 0x8054)
+#define PCIE_RDDMA0_LLPTR_LOW(base)            ((base) + 0x8058)
+#define PCIE_RDDMA0_LLPTR_HIGH(base)           ((base) + 0x805c)
+#define PCIE_RDDMA1_CHNL_CNTRL(base)           ((base) + 0x8060)
+#define PCIE_RDDMA1_XFR_SIZE(base)             ((base) + 0x8064)
+#define PCIE_RDDMA1_SAR_LOW(base)              ((base) + 0x8068)
+#define PCIE_RDDMA1_SAR_HIGH(base)             ((base) + 0x806c)
+#define PCIE_RDDMA1_DAR_LOW(base)              ((base) + 0x8070)
+#define PCIE_RDDMA1_DAR_HIGH(base)             ((base) + 0x8074)
+#define PCIE_RDDMA1_LLPTR_LOW(base)            ((base) + 0x8078)
+#define PCIE_RDDMA1_LLPTR_HIGH(base)           ((base) + 0x807c)
+
+#define PCIE_ID(base)                          ((base) + 0x0000)
+#define PCIE_CMD(base)                         ((base) + 0x0004)
+#define PCIE_BAR(base, n)                      ((base) + 0x0010 + ((n) << 2))
+#define PCIE_CAP_PTR(base)                     ((base) + 0x0034)
+#define PCIE_MSI_LBAR(base)                    ((base) + 0x0054)
+#define PCIE_MSI_CTRL(base)                    ((base) + 0x0050)
+#define PCIE_MSI_ADDR_L(base)                  ((base) + 0x0054)
+#define PCIE_MSI_ADDR_H(base)                  ((base) + 0x0058)
+#define PCIE_MSI_DATA(base)                    ((base) + 0x005C)
+#define PCIE_MSI_MASK_BIT(base)                        ((base) + 0x0060)
+#define PCIE_MSI_PEND_BIT(base)                        ((base) + 0x0064)
+#define PCIE_DEVCAP(base)                      ((base) + 0x0074)
+#define PCIE_DEVCTLSTS(base)                   ((base) + 0x0078)
+
+#define PCIE_CMDSTS(base)                      ((base) + 0x0004)
+#define PCIE_LINK_STAT(base)                   ((base) + 0x80)
+#define PCIE_LINK_CTL2(base)                   ((base) + 0xa0)
+#define PCIE_ASPM_L1_CTRL(base)                        ((base) + 0x70c)
+#define PCIE_ASPM_LINK_CTRL(base)              (PCIE_LINK_STAT)
+#define PCIE_ASPM_L1_SUBSTATE_TIMING(base)     ((base) + 0xB44)
+#define PCIE_L1SUB_CTRL1(base)                 ((base) + 0x150)
+#define PCIE_PMCSR(base)                       ((base) + 0x44)
+#define PCIE_CFG_SPACE_LIMIT(base)             ((base) + 0x100)
+
+/* PCIe link defines */
+#define PEARL_PCIE_LINKUP                      (0x7)
+#define PEARL_PCIE_DATA_LINK                   (BIT(0))
+#define PEARL_PCIE_PHY_LINK                    (BIT(1))
+#define PEARL_PCIE_LINK_RST                    (BIT(3))
+#define PEARL_PCIE_FATAL_ERR                   (BIT(5))
+#define PEARL_PCIE_NONFATAL_ERR                        (BIT(6))
+
+/* PCIe Lane defines */
+#define PCIE_G2_LANE_X1                                ((BIT(0)) << 16)
+#define PCIE_G2_LANE_X2                                ((BIT(0) | BIT(1)) << 16)
+
+/* PCIe DLL link enable */
+#define PCIE_DLL_LINK_EN                       ((BIT(0)) << 5)
+
+#define PCIE_LINK_GEN1                         (BIT(0))
+#define PCIE_LINK_GEN2                         (BIT(1))
+#define PCIE_LINK_GEN3                         (BIT(2))
+#define PCIE_LINK_MODE(x)                      (((x) >> 16) & 0x7)
+
+#define MSI_EN                                 (BIT(0))
+#define MSI_64_EN                              (BIT(7))
+#define PCIE_MSI_ADDR_OFFSET(a)                        ((a) & 0xFFFF)
+#define PCIE_MSI_ADDR_ALIGN(a)                 ((a) & (~0xFFFF))
+
+#define PCIE_BAR_MASK(base, n)                 ((base) + 0x1010 + ((n) << 2))
+#define PCIE_MAX_BAR                           (6)
+
+#define PCIE_ATU_VIEW(base)                    ((base) + 0x0900)
+#define PCIE_ATU_CTL1(base)                    ((base) + 0x0904)
+#define PCIE_ATU_CTL2(base)                    ((base) + 0x0908)
+#define PCIE_ATU_LBAR(base)                    ((base) + 0x090c)
+#define PCIE_ATU_UBAR(base)                    ((base) + 0x0910)
+#define PCIE_ATU_LAR(base)                     ((base) + 0x0914)
+#define PCIE_ATU_LTAR(base)                    ((base) + 0x0918)
+#define PCIE_ATU_UTAR(base)                    ((base) + 0x091c)
+
+#define PCIE_MSI_ADDR_LOWER(base)              ((base) + 0x0820)
+#define PCIE_MSI_ADDR_UPPER(base)              ((base) + 0x0824)
+#define PCIE_MSI_ENABLE(base)                  ((base) + 0x0828)
+#define PCIE_MSI_MASK_RC(base)                 ((base) + 0x082c)
+#define PCIE_MSI_STATUS(base)                  ((base) + 0x0830)
+#define PEARL_PCIE_MSI_REGION                  (0xce000000)
+#define PEARL_PCIE_MSI_DATA                    (0)
+#define PCIE_MSI_GPIO(base)                    ((base) + 0x0888)
+
+#define PCIE_HDP_HOST_QUEUE_FULL       (BIT(17))
+#define USE_BAR_MATCH_MODE
+#define PCIE_ATU_OB_REGION             (BIT(0))
+#define PCIE_ATU_EN_REGION             (BIT(31))
+#define PCIE_ATU_EN_MATCH              (BIT(30))
+#define PCIE_BASE_REGION               (0xb0000000)
+#define PCIE_MEM_MAP_SIZE              (512 * 1024)
+
+#define PCIE_OB_REG_REGION             (0xcf000000)
+#define PCIE_CONFIG_REGION             (0xcf000000)
+#define PCIE_CONFIG_SIZE               (4096)
+#define PCIE_CONFIG_CH                 (1)
+
+/* inbound mapping */
+#define PCIE_IB_BAR0                   (0x00000000)    /* ddr */
+#define PCIE_IB_BAR0_CH                        (0)
+#define PCIE_IB_BAR3                   (0xe0000000)    /* sys_reg */
+#define PCIE_IB_BAR3_CH                        (1)
+
+/* outbound mapping */
+#define PCIE_MEM_CH                    (0)
+#define PCIE_REG_CH                    (1)
+#define PCIE_MEM_REGION                        (0xc0000000)
+#define        PCIE_MEM_SIZE                   (0x000fffff)
+#define PCIE_MEM_TAR                   (0x80000000)
+
+#define PCIE_MSI_REGION                        (0xce000000)
+#define PCIE_MSI_SIZE                  (KBYTE(4) - 1)
+#define PCIE_MSI_CH                    (1)
+
+/* size of config region */
+#define PCIE_CFG_SIZE                  (0x0000ffff)
+
+#define PCIE_ATU_DIR_IB                        (BIT(31))
+#define PCIE_ATU_DIR_OB                        (0)
+#define PCIE_ATU_DIR_CFG               (2)
+#define PCIE_ATU_DIR_MATCH_IB          (BIT(31) | BIT(30))
+
+#define PCIE_DMA_WR_0                  (0)
+#define PCIE_DMA_WR_1                  (1)
+#define PCIE_DMA_RD_0                  (2)
+#define PCIE_DMA_RD_1                  (3)
+
+#define PCIE_DMA_CHNL_CNTRL_CB         (BIT(0))
+#define PCIE_DMA_CHNL_CNTRL_TCB                (BIT(1))
+#define PCIE_DMA_CHNL_CNTRL_LLP                (BIT(2))
+#define PCIE_DMA_CHNL_CNTRL_LIE                (BIT(3))
+#define PCIE_DMA_CHNL_CNTRL_RIE                (BIT(4))
+#define PCIE_DMA_CHNL_CNTRL_CSS                (BIT(8))
+#define PCIE_DMA_CHNL_CNTRL_LLE                (BIT(9))
+#define PCIE_DMA_CHNL_CNTRL_TLP                (BIT(26))
+
+#define PCIE_DMA_CHNL_CONTEXT_RD       (BIT(31))
+#define PCIE_DMA_CHNL_CONTEXT_WR       (0)
+#define PCIE_MAX_BAR                   (6)
+
+/* PCIe HDP interrupt status definition */
+#define PCIE_HDP_INT_EP_RXDMA          (BIT(0))
+#define PCIE_HDP_INT_HBM_UF            (BIT(1))
+#define PCIE_HDP_INT_RX_LEN_ERR                (BIT(2))
+#define PCIE_HDP_INT_RX_HDR_LEN_ERR    (BIT(3))
+#define PCIE_HDP_INT_EP_TXDMA          (BIT(12))
+#define PCIE_HDP_INT_HHBM_UF           (BIT(13))
+#define PCIE_HDP_INT_EP_TXEMPTY                (BIT(15))
+#define PCIE_HDP_INT_IPC               (BIT(29))
+
+/* PCIe interrupt status definition */
+#define PCIE_INT_MSI                   (BIT(24))
+#define PCIE_INT_INTX                  (BIT(23))
+
+/* PCIe legacy INTx */
+#define PEARL_PCIE_CFG0_OFFSET         (0x6C)
+#define PEARL_ASSERT_INTX              (BIT(9))
+
+/* SYS CTL regs */
+#define QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET      (0x001C)
+
+#define QTN_PEARL_IPC_IRQ_WORD(irq)    (BIT(irq) | BIT(irq + 16))
+#define QTN_PEARL_LHOST_IPC_IRQ                (6)
+#define QTN_PEARL_LHOST_EP_RESET       (7)
+
+#endif /* __PEARL_PCIE_H */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c
deleted file mode 100644 (file)
index 97cc7f2..0000000
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * Copyright (c) 2015-2016 Quantenna Communications, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/completion.h>
-#include <linux/crc32.h>
-#include <linux/spinlock.h>
-#include <linux/circ_buf.h>
-#include <linux/log2.h>
-
-#include "qtn_hw_ids.h"
-#include "pcie_bus_priv.h"
-#include "core.h"
-#include "bus.h"
-#include "debug.h"
-
-static bool use_msi = true;
-module_param(use_msi, bool, 0644);
-MODULE_PARM_DESC(use_msi, "set 0 to use legacy interrupt");
-
-static unsigned int tx_bd_size_param = 32;
-module_param(tx_bd_size_param, uint, 0644);
-MODULE_PARM_DESC(tx_bd_size_param, "Tx descriptors queue size, power of two");
-
-static unsigned int rx_bd_size_param = 256;
-module_param(rx_bd_size_param, uint, 0644);
-MODULE_PARM_DESC(rx_bd_size_param, "Rx descriptors queue size, power of two");
-
-static u8 flashboot = 1;
-module_param(flashboot, byte, 0644);
-MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS");
-
-#define DRV_NAME       "qtnfmac_pearl_pcie"
-
-static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg)
-{
-       writel(val, basereg);
-
-       /* flush posted write */
-       readl(basereg);
-}
-
-static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       priv->pcie_irq_mask = (PCIE_HDP_INT_RX_BITS | PCIE_HDP_INT_TX_BITS);
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       writel(0x0, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       priv->pcie_irq_mask |= PCIE_HDP_INT_RX_BITS;
-       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       priv->pcie_irq_mask &= ~PCIE_HDP_INT_RX_BITS;
-       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_en_txdone_irq(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       priv->pcie_irq_mask |= PCIE_HDP_INT_TX_BITS;
-       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_bus_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->irq_lock, flags);
-       priv->pcie_irq_mask &= ~PCIE_HDP_INT_TX_BITS;
-       writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       spin_unlock_irqrestore(&priv->irq_lock, flags);
-}
-
-static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv)
-{
-       struct pci_dev *pdev = priv->pdev;
-
-       /* fall back to legacy INTx interrupts by default */
-       priv->msi_enabled = 0;
-
-       /* check if MSI capability is available */
-       if (use_msi) {
-               if (!pci_enable_msi(pdev)) {
-                       pr_debug("MSI interrupt enabled\n");
-                       priv->msi_enabled = 1;
-               } else {
-                       pr_warn("failed to enable MSI interrupts");
-               }
-       }
-
-       if (!priv->msi_enabled) {
-               pr_warn("legacy PCIE interrupts enabled\n");
-               pci_intx(pdev, 1);
-       }
-}
-
-static void qtnf_deassert_intx(struct qtnf_pcie_bus_priv *priv)
-{
-       void __iomem *reg = priv->sysctl_bar + PEARL_PCIE_CFG0_OFFSET;
-       u32 cfg;
-
-       cfg = readl(reg);
-       cfg &= ~PEARL_ASSERT_INTX;
-       qtnf_non_posted_write(cfg, reg);
-}
-
-static void qtnf_reset_card(struct qtnf_pcie_bus_priv *priv)
-{
-       const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET);
-       void __iomem *reg = priv->sysctl_bar +
-                           QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET;
-
-       qtnf_non_posted_write(data, reg);
-       msleep(QTN_EP_RESET_WAIT_MS);
-       pci_restore_state(priv->pdev);
-}
-
-static void qtnf_ipc_gen_ep_int(void *arg)
-{
-       const struct qtnf_pcie_bus_priv *priv = arg;
-       const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_IPC_IRQ);
-       void __iomem *reg = priv->sysctl_bar +
-                           QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET;
-
-       qtnf_non_posted_write(data, reg);
-}
-
-static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index)
-{
-       void __iomem *vaddr;
-       dma_addr_t busaddr;
-       size_t len;
-       int ret;
-
-       ret = pcim_iomap_regions(priv->pdev, 1 << index, DRV_NAME);
-       if (ret)
-               return IOMEM_ERR_PTR(ret);
-
-       busaddr = pci_resource_start(priv->pdev, index);
-       len = pci_resource_len(priv->pdev, index);
-       vaddr = pcim_iomap_table(priv->pdev)[index];
-       if (!vaddr)
-               return IOMEM_ERR_PTR(-ENOMEM);
-
-       pr_debug("BAR%u vaddr=0x%p busaddr=%pad len=%u\n",
-                index, vaddr, &busaddr, (int)len);
-
-       return vaddr;
-}
-
-static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len)
-{
-       struct qtnf_pcie_bus_priv *priv = arg;
-       struct qtnf_bus *bus = pci_get_drvdata(priv->pdev);
-       struct sk_buff *skb;
-
-       if (unlikely(len == 0)) {
-               pr_warn("zero length packet received\n");
-               return;
-       }
-
-       skb = __dev_alloc_skb(len, GFP_KERNEL);
-
-       if (unlikely(!skb)) {
-               pr_err("failed to allocate skb\n");
-               return;
-       }
-
-       skb_put_data(skb, buf, len);
-
-       qtnf_trans_handle_rx_ctl_packet(bus, skb);
-}
-
-static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv)
-{
-       struct qtnf_shm_ipc_region __iomem *ipc_tx_reg;
-       struct qtnf_shm_ipc_region __iomem *ipc_rx_reg;
-       const struct qtnf_shm_ipc_int ipc_int = { qtnf_ipc_gen_ep_int, priv };
-       const struct qtnf_shm_ipc_rx_callback rx_callback = {
-                                       qtnf_pcie_control_rx_callback, priv };
-
-       ipc_tx_reg = &priv->bda->bda_shm_reg1;
-       ipc_rx_reg = &priv->bda->bda_shm_reg2;
-
-       qtnf_shm_ipc_init(&priv->shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND,
-                         ipc_tx_reg, priv->workqueue,
-                         &ipc_int, &rx_callback);
-       qtnf_shm_ipc_init(&priv->shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND,
-                         ipc_rx_reg, priv->workqueue,
-                         &ipc_int, &rx_callback);
-
-       return 0;
-}
-
-static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv)
-{
-       qtnf_shm_ipc_free(&priv->shm_ipc_ep_in);
-       qtnf_shm_ipc_free(&priv->shm_ipc_ep_out);
-}
-
-static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv)
-{
-       int ret = -ENOMEM;
-
-       priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR);
-       if (IS_ERR(priv->sysctl_bar)) {
-               pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR);
-               return ret;
-       }
-
-       priv->dmareg_bar = qtnf_map_bar(priv, QTN_DMA_BAR);
-       if (IS_ERR(priv->dmareg_bar)) {
-               pr_err("failed to map BAR%u\n", QTN_DMA_BAR);
-               return ret;
-       }
-
-       priv->epmem_bar = qtnf_map_bar(priv, QTN_SHMEM_BAR);
-       if (IS_ERR(priv->epmem_bar)) {
-               pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR);
-               return ret;
-       }
-
-       priv->pcie_reg_base = priv->dmareg_bar;
-       priv->bda = priv->epmem_bar;
-       writel(priv->msi_enabled, &priv->bda->bda_rc_msi_enabled);
-
-       return 0;
-}
-
-static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv)
-{
-       struct pci_dev *pdev = priv->pdev;
-       struct pci_dev *parent;
-       int mps_p, mps_o, mps_m, mps;
-       int ret;
-
-       /* current mps */
-       mps_o = pcie_get_mps(pdev);
-
-       /* maximum supported mps */
-       mps_m = 128 << pdev->pcie_mpss;
-
-       /* suggested new mps value */
-       mps = mps_m;
-
-       if (pdev->bus && pdev->bus->self) {
-               /* parent (bus) mps */
-               parent = pdev->bus->self;
-
-               if (pci_is_pcie(parent)) {
-                       mps_p = pcie_get_mps(parent);
-                       mps = min(mps_m, mps_p);
-               }
-       }
-
-       ret = pcie_set_mps(pdev, mps);
-       if (ret) {
-               pr_err("failed to set mps to %d, keep using current %d\n",
-                      mps, mps_o);
-               priv->mps = mps_o;
-               return;
-       }
-
-       pr_debug("set mps to %d (was %d, max %d)\n", mps, mps_o, mps_m);
-       priv->mps = mps;
-}
-
-static int qtnf_is_state(__le32 __iomem *reg, u32 state)
-{
-       u32 s = readl(reg);
-
-       return s & state;
-}
-
-static void qtnf_set_state(__le32 __iomem *reg, u32 state)
-{
-       u32 s = readl(reg);
-
-       qtnf_non_posted_write(state | s, reg);
-}
-
-static void qtnf_clear_state(__le32 __iomem *reg, u32 state)
-{
-       u32 s = readl(reg);
-
-       qtnf_non_posted_write(s & ~state, reg);
-}
-
-static int qtnf_poll_state(__le32 __iomem *reg, u32 state, u32 delay_in_ms)
-{
-       u32 timeout = 0;
-
-       while ((qtnf_is_state(reg, state) == 0)) {
-               usleep_range(1000, 1200);
-               if (++timeout > delay_in_ms)
-                       return -1;
-       }
-
-       return 0;
-}
-
-static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv)
-{
-       struct sk_buff **vaddr;
-       int len;
-
-       len = priv->tx_bd_num * sizeof(*priv->tx_skb) +
-               priv->rx_bd_num * sizeof(*priv->rx_skb);
-       vaddr = devm_kzalloc(&priv->pdev->dev, len, GFP_KERNEL);
-
-       if (!vaddr)
-               return -ENOMEM;
-
-       priv->tx_skb = vaddr;
-
-       vaddr += priv->tx_bd_num;
-       priv->rx_skb = vaddr;
-
-       return 0;
-}
-
-static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv)
-{
-       dma_addr_t paddr;
-       void *vaddr;
-       int len;
-
-       len = priv->tx_bd_num * sizeof(struct qtnf_tx_bd) +
-               priv->rx_bd_num * sizeof(struct qtnf_rx_bd);
-
-       vaddr = dmam_alloc_coherent(&priv->pdev->dev, len, &paddr, GFP_KERNEL);
-       if (!vaddr)
-               return -ENOMEM;
-
-       /* tx bd */
-
-       memset(vaddr, 0, len);
-
-       priv->bd_table_vaddr = vaddr;
-       priv->bd_table_paddr = paddr;
-       priv->bd_table_len = len;
-
-       priv->tx_bd_vbase = vaddr;
-       priv->tx_bd_pbase = paddr;
-
-       pr_debug("TX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
-
-       priv->tx_bd_r_index = 0;
-       priv->tx_bd_w_index = 0;
-
-       /* rx bd */
-
-       vaddr = ((struct qtnf_tx_bd *)vaddr) + priv->tx_bd_num;
-       paddr += priv->tx_bd_num * sizeof(struct qtnf_tx_bd);
-
-       priv->rx_bd_vbase = vaddr;
-       priv->rx_bd_pbase = paddr;
-
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       writel(QTN_HOST_HI32(paddr),
-              PCIE_HDP_TX_HOST_Q_BASE_H(priv->pcie_reg_base));
-#endif
-       writel(QTN_HOST_LO32(paddr),
-              PCIE_HDP_TX_HOST_Q_BASE_L(priv->pcie_reg_base));
-       writel(priv->rx_bd_num | (sizeof(struct qtnf_rx_bd)) << 16,
-              PCIE_HDP_TX_HOST_Q_SZ_CTRL(priv->pcie_reg_base));
-
-       pr_debug("RX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
-
-       return 0;
-}
-
-static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 index)
-{
-       struct qtnf_rx_bd *rxbd;
-       struct sk_buff *skb;
-       dma_addr_t paddr;
-
-       skb = __netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE, GFP_ATOMIC);
-       if (!skb) {
-               priv->rx_skb[index] = NULL;
-               return -ENOMEM;
-       }
-
-       priv->rx_skb[index] = skb;
-       rxbd = &priv->rx_bd_vbase[index];
-
-       paddr = pci_map_single(priv->pdev, skb->data,
-                              SKB_BUF_SIZE, PCI_DMA_FROMDEVICE);
-       if (pci_dma_mapping_error(priv->pdev, paddr)) {
-               pr_err("skb DMA mapping error: %pad\n", &paddr);
-               return -ENOMEM;
-       }
-
-       /* keep rx skb paddrs in rx buffer descriptors for cleanup purposes */
-       rxbd->addr = cpu_to_le32(QTN_HOST_LO32(paddr));
-       rxbd->addr_h = cpu_to_le32(QTN_HOST_HI32(paddr));
-       rxbd->info = 0x0;
-
-       priv->rx_bd_w_index = index;
-
-       /* sync up all descriptor updates */
-       wmb();
-
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       writel(QTN_HOST_HI32(paddr),
-              PCIE_HDP_HHBM_BUF_PTR_H(priv->pcie_reg_base));
-#endif
-       writel(QTN_HOST_LO32(paddr),
-              PCIE_HDP_HHBM_BUF_PTR(priv->pcie_reg_base));
-
-       writel(index, PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base));
-       return 0;
-}
-
-static int alloc_rx_buffers(struct qtnf_pcie_bus_priv *priv)
-{
-       u16 i;
-       int ret = 0;
-
-       memset(priv->rx_bd_vbase, 0x0,
-              priv->rx_bd_num * sizeof(struct qtnf_rx_bd));
-
-       for (i = 0; i < priv->rx_bd_num; i++) {
-               ret = skb2rbd_attach(priv, i);
-               if (ret)
-                       break;
-       }
-
-       return ret;
-}
-
-/* all rx/tx activity should have ceased before calling this function */
-static void qtnf_free_xfer_buffers(struct qtnf_pcie_bus_priv *priv)
-{
-       struct qtnf_tx_bd *txbd;
-       struct qtnf_rx_bd *rxbd;
-       struct sk_buff *skb;
-       dma_addr_t paddr;
-       int i;
-
-       /* free rx buffers */
-       for (i = 0; i < priv->rx_bd_num; i++) {
-               if (priv->rx_skb && priv->rx_skb[i]) {
-                       rxbd = &priv->rx_bd_vbase[i];
-                       skb = priv->rx_skb[i];
-                       paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h),
-                                             le32_to_cpu(rxbd->addr));
-                       pci_unmap_single(priv->pdev, paddr, SKB_BUF_SIZE,
-                                        PCI_DMA_FROMDEVICE);
-                       dev_kfree_skb_any(skb);
-                       priv->rx_skb[i] = NULL;
-               }
-       }
-
-       /* free tx buffers */
-       for (i = 0; i < priv->tx_bd_num; i++) {
-               if (priv->tx_skb && priv->tx_skb[i]) {
-                       txbd = &priv->tx_bd_vbase[i];
-                       skb = priv->tx_skb[i];
-                       paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
-                                             le32_to_cpu(txbd->addr));
-                       pci_unmap_single(priv->pdev, paddr, skb->len,
-                                        PCI_DMA_TODEVICE);
-                       dev_kfree_skb_any(skb);
-                       priv->tx_skb[i] = NULL;
-               }
-       }
-}
-
-static int qtnf_hhbm_init(struct qtnf_pcie_bus_priv *priv)
-{
-       u32 val;
-
-       val = readl(PCIE_HHBM_CONFIG(priv->pcie_reg_base));
-       val |= HHBM_CONFIG_SOFT_RESET;
-       writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base));
-       usleep_range(50, 100);
-       val &= ~HHBM_CONFIG_SOFT_RESET;
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       val |= HHBM_64BIT;
-#endif
-       writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base));
-       writel(priv->rx_bd_num, PCIE_HHBM_Q_LIMIT_REG(priv->pcie_reg_base));
-
-       return 0;
-}
-
-static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv)
-{
-       int ret;
-       u32 val;
-
-       priv->tx_bd_num = tx_bd_size_param;
-       priv->rx_bd_num = rx_bd_size_param;
-       priv->rx_bd_w_index = 0;
-       priv->rx_bd_r_index = 0;
-
-       if (!priv->tx_bd_num || !is_power_of_2(priv->tx_bd_num)) {
-               pr_err("tx_bd_size_param %u is not power of two\n",
-                      priv->tx_bd_num);
-               return -EINVAL;
-       }
-
-       val = priv->tx_bd_num * sizeof(struct qtnf_tx_bd);
-       if (val > PCIE_HHBM_MAX_SIZE) {
-               pr_err("tx_bd_size_param %u is too large\n",
-                      priv->tx_bd_num);
-               return -EINVAL;
-       }
-
-       if (!priv->rx_bd_num || !is_power_of_2(priv->rx_bd_num)) {
-               pr_err("rx_bd_size_param %u is not power of two\n",
-                      priv->rx_bd_num);
-               return -EINVAL;
-       }
-
-       val = priv->rx_bd_num * sizeof(dma_addr_t);
-       if (val > PCIE_HHBM_MAX_SIZE) {
-               pr_err("rx_bd_size_param %u is too large\n",
-                      priv->rx_bd_num);
-               return -EINVAL;
-       }
-
-       ret = qtnf_hhbm_init(priv);
-       if (ret) {
-               pr_err("failed to init h/w queues\n");
-               return ret;
-       }
-
-       ret = alloc_skb_array(priv);
-       if (ret) {
-               pr_err("failed to allocate skb array\n");
-               return ret;
-       }
-
-       ret = alloc_bd_table(priv);
-       if (ret) {
-               pr_err("failed to allocate bd table\n");
-               return ret;
-       }
-
-       ret = alloc_rx_buffers(priv);
-       if (ret) {
-               pr_err("failed to allocate rx buffers\n");
-               return ret;
-       }
-
-       return ret;
-}
-
-static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv)
-{
-       struct qtnf_tx_bd *txbd;
-       struct sk_buff *skb;
-       unsigned long flags;
-       dma_addr_t paddr;
-       u32 tx_done_index;
-       int count = 0;
-       int i;
-
-       spin_lock_irqsave(&priv->tx_reclaim_lock, flags);
-
-       tx_done_index = readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
-                       & (priv->tx_bd_num - 1);
-
-       i = priv->tx_bd_r_index;
-
-       while (CIRC_CNT(tx_done_index, i, priv->tx_bd_num)) {
-               skb = priv->tx_skb[i];
-               if (likely(skb)) {
-                       txbd = &priv->tx_bd_vbase[i];
-                       paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
-                                             le32_to_cpu(txbd->addr));
-                       pci_unmap_single(priv->pdev, paddr, skb->len,
-                                        PCI_DMA_TODEVICE);
-
-                       if (skb->dev) {
-                               qtnf_update_tx_stats(skb->dev, skb);
-                               if (unlikely(priv->tx_stopped)) {
-                                       qtnf_wake_all_queues(skb->dev);
-                                       priv->tx_stopped = 0;
-                               }
-                       }
-
-                       dev_kfree_skb_any(skb);
-               }
-
-               priv->tx_skb[i] = NULL;
-               count++;
-
-               if (++i >= priv->tx_bd_num)
-                       i = 0;
-       }
-
-       priv->tx_reclaim_done += count;
-       priv->tx_reclaim_req++;
-       priv->tx_bd_r_index = i;
-
-       spin_unlock_irqrestore(&priv->tx_reclaim_lock, flags);
-}
-
-static int qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv)
-{
-       if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
-                       priv->tx_bd_num)) {
-               qtnf_pcie_data_tx_reclaim(priv);
-
-               if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
-                               priv->tx_bd_num)) {
-                       pr_warn_ratelimited("reclaim full Tx queue\n");
-                       priv->tx_full_count++;
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       dma_addr_t txbd_paddr, skb_paddr;
-       struct qtnf_tx_bd *txbd;
-       unsigned long flags;
-       int len, i;
-       u32 info;
-       int ret = 0;
-
-       spin_lock_irqsave(&priv->tx0_lock, flags);
-
-       if (!qtnf_tx_queue_ready(priv)) {
-               if (skb->dev) {
-                       netif_tx_stop_all_queues(skb->dev);
-                       priv->tx_stopped = 1;
-               }
-
-               spin_unlock_irqrestore(&priv->tx0_lock, flags);
-               return NETDEV_TX_BUSY;
-       }
-
-       i = priv->tx_bd_w_index;
-       priv->tx_skb[i] = skb;
-       len = skb->len;
-
-       skb_paddr = pci_map_single(priv->pdev, skb->data,
-                                  skb->len, PCI_DMA_TODEVICE);
-       if (pci_dma_mapping_error(priv->pdev, skb_paddr)) {
-               pr_err("skb DMA mapping error: %pad\n", &skb_paddr);
-               ret = -ENOMEM;
-               goto tx_done;
-       }
-
-       txbd = &priv->tx_bd_vbase[i];
-       txbd->addr = cpu_to_le32(QTN_HOST_LO32(skb_paddr));
-       txbd->addr_h = cpu_to_le32(QTN_HOST_HI32(skb_paddr));
-
-       info = (len & QTN_PCIE_TX_DESC_LEN_MASK) << QTN_PCIE_TX_DESC_LEN_SHIFT;
-       txbd->info = cpu_to_le32(info);
-
-       /* sync up all descriptor updates before passing them to EP */
-       dma_wmb();
-
-       /* write new TX descriptor to PCIE_RX_FIFO on EP */
-       txbd_paddr = priv->tx_bd_pbase + i * sizeof(struct qtnf_tx_bd);
-
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       writel(QTN_HOST_HI32(txbd_paddr),
-              PCIE_HDP_HOST_WR_DESC0_H(priv->pcie_reg_base));
-#endif
-       writel(QTN_HOST_LO32(txbd_paddr),
-              PCIE_HDP_HOST_WR_DESC0(priv->pcie_reg_base));
-
-       if (++i >= priv->tx_bd_num)
-               i = 0;
-
-       priv->tx_bd_w_index = i;
-
-tx_done:
-       if (ret && skb) {
-               pr_err_ratelimited("drop skb\n");
-               if (skb->dev)
-                       skb->dev->stats.tx_dropped++;
-               dev_kfree_skb_any(skb);
-       }
-
-       priv->tx_done_count++;
-       spin_unlock_irqrestore(&priv->tx0_lock, flags);
-
-       qtnf_pcie_data_tx_reclaim(priv);
-
-       return NETDEV_TX_OK;
-}
-
-static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       int ret;
-
-       ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len);
-
-       if (ret == -ETIMEDOUT) {
-               pr_err("EP firmware is dead\n");
-               bus->fw_state = QTNF_FW_STATE_EP_DEAD;
-       }
-
-       return ret;
-}
-
-static irqreturn_t qtnf_interrupt(int irq, void *data)
-{
-       struct qtnf_bus *bus = (struct qtnf_bus *)data;
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       u32 status;
-
-       priv->pcie_irq_count++;
-       status = readl(PCIE_HDP_INT_STATUS(priv->pcie_reg_base));
-
-       qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_in);
-       qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_out);
-
-       if (!(status & priv->pcie_irq_mask))
-               goto irq_done;
-
-       if (status & PCIE_HDP_INT_RX_BITS)
-               priv->pcie_irq_rx_count++;
-
-       if (status & PCIE_HDP_INT_TX_BITS)
-               priv->pcie_irq_tx_count++;
-
-       if (status & PCIE_HDP_INT_HHBM_UF)
-               priv->pcie_irq_uf_count++;
-
-       if (status & PCIE_HDP_INT_RX_BITS) {
-               qtnf_dis_rxdone_irq(priv);
-               napi_schedule(&bus->mux_napi);
-       }
-
-       if (status & PCIE_HDP_INT_TX_BITS) {
-               qtnf_dis_txdone_irq(priv);
-               tasklet_hi_schedule(&priv->reclaim_tq);
-       }
-
-irq_done:
-       /* H/W workaround: clean all bits, not only enabled */
-       qtnf_non_posted_write(~0U, PCIE_HDP_INT_STATUS(priv->pcie_reg_base));
-
-       if (!priv->msi_enabled)
-               qtnf_deassert_intx(priv);
-
-       return IRQ_HANDLED;
-}
-
-static int qtnf_rx_data_ready(struct qtnf_pcie_bus_priv *priv)
-{
-       u16 index = priv->rx_bd_r_index;
-       struct qtnf_rx_bd *rxbd;
-       u32 descw;
-
-       rxbd = &priv->rx_bd_vbase[index];
-       descw = le32_to_cpu(rxbd->info);
-
-       if (descw & QTN_TXDONE_MASK)
-               return 1;
-
-       return 0;
-}
-
-static int qtnf_rx_poll(struct napi_struct *napi, int budget)
-{
-       struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi);
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       struct net_device *ndev = NULL;
-       struct sk_buff *skb = NULL;
-       int processed = 0;
-       struct qtnf_rx_bd *rxbd;
-       dma_addr_t skb_paddr;
-       int consume;
-       u32 descw;
-       u32 psize;
-       u16 r_idx;
-       u16 w_idx;
-       int ret;
-
-       while (processed < budget) {
-
-
-               if (!qtnf_rx_data_ready(priv))
-                       goto rx_out;
-
-               r_idx = priv->rx_bd_r_index;
-               rxbd = &priv->rx_bd_vbase[r_idx];
-               descw = le32_to_cpu(rxbd->info);
-
-               skb = priv->rx_skb[r_idx];
-               psize = QTN_GET_LEN(descw);
-               consume = 1;
-
-               if (!(descw & QTN_TXDONE_MASK)) {
-                       pr_warn("skip invalid rxbd[%d]\n", r_idx);
-                       consume = 0;
-               }
-
-               if (!skb) {
-                       pr_warn("skip missing rx_skb[%d]\n", r_idx);
-                       consume = 0;
-               }
-
-               if (skb && (skb_tailroom(skb) <  psize)) {
-                       pr_err("skip packet with invalid length: %u > %u\n",
-                              psize, skb_tailroom(skb));
-                       consume = 0;
-               }
-
-               if (skb) {
-                       skb_paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h),
-                                                 le32_to_cpu(rxbd->addr));
-                       pci_unmap_single(priv->pdev, skb_paddr, SKB_BUF_SIZE,
-                                        PCI_DMA_FROMDEVICE);
-               }
-
-               if (consume) {
-                       skb_put(skb, psize);
-                       ndev = qtnf_classify_skb(bus, skb);
-                       if (likely(ndev)) {
-                               qtnf_update_rx_stats(ndev, skb);
-                               skb->protocol = eth_type_trans(skb, ndev);
-                               napi_gro_receive(napi, skb);
-                       } else {
-                               pr_debug("drop untagged skb\n");
-                               bus->mux_dev.stats.rx_dropped++;
-                               dev_kfree_skb_any(skb);
-                       }
-               } else {
-                       if (skb) {
-                               bus->mux_dev.stats.rx_dropped++;
-                               dev_kfree_skb_any(skb);
-                       }
-               }
-
-               priv->rx_skb[r_idx] = NULL;
-               if (++r_idx >= priv->rx_bd_num)
-                       r_idx = 0;
-
-               priv->rx_bd_r_index = r_idx;
-
-               /* repalce processed buffer by a new one */
-               w_idx = priv->rx_bd_w_index;
-               while (CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
-                                 priv->rx_bd_num) > 0) {
-                       if (++w_idx >= priv->rx_bd_num)
-                               w_idx = 0;
-
-                       ret = skb2rbd_attach(priv, w_idx);
-                       if (ret) {
-                               pr_err("failed to allocate new rx_skb[%d]\n",
-                                      w_idx);
-                               break;
-                       }
-               }
-
-               processed++;
-       }
-
-rx_out:
-       if (processed < budget) {
-               napi_complete(napi);
-               qtnf_en_rxdone_irq(priv);
-       }
-
-       return processed;
-}
-
-static void
-qtnf_pcie_data_tx_timeout(struct qtnf_bus *bus, struct net_device *ndev)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-
-       tasklet_hi_schedule(&priv->reclaim_tq);
-}
-
-static void qtnf_pcie_data_rx_start(struct qtnf_bus *bus)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-
-       qtnf_enable_hdp_irqs(priv);
-       napi_enable(&bus->mux_napi);
-}
-
-static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-
-       napi_disable(&bus->mux_napi);
-       qtnf_disable_hdp_irqs(priv);
-}
-
-static const struct qtnf_bus_ops qtnf_pcie_bus_ops = {
-       /* control path methods */
-       .control_tx     = qtnf_pcie_control_tx,
-
-       /* data path methods */
-       .data_tx                = qtnf_pcie_data_tx,
-       .data_tx_timeout        = qtnf_pcie_data_tx_timeout,
-       .data_rx_start          = qtnf_pcie_data_rx_start,
-       .data_rx_stop           = qtnf_pcie_data_rx_stop,
-};
-
-static int qtnf_dbg_mps_show(struct seq_file *s, void *data)
-{
-       struct qtnf_bus *bus = dev_get_drvdata(s->private);
-       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
-
-       seq_printf(s, "%d\n", priv->mps);
-
-       return 0;
-}
-
-static int qtnf_dbg_msi_show(struct seq_file *s, void *data)
-{
-       struct qtnf_bus *bus = dev_get_drvdata(s->private);
-       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
-
-       seq_printf(s, "%u\n", priv->msi_enabled);
-
-       return 0;
-}
-
-static int qtnf_dbg_irq_stats(struct seq_file *s, void *data)
-{
-       struct qtnf_bus *bus = dev_get_drvdata(s->private);
-       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
-       u32 reg = readl(PCIE_HDP_INT_EN(priv->pcie_reg_base));
-       u32 status;
-
-       seq_printf(s, "pcie_irq_count(%u)\n", priv->pcie_irq_count);
-       seq_printf(s, "pcie_irq_tx_count(%u)\n", priv->pcie_irq_tx_count);
-       status = reg &  PCIE_HDP_INT_TX_BITS;
-       seq_printf(s, "pcie_irq_tx_status(%s)\n",
-                  (status == PCIE_HDP_INT_TX_BITS) ? "EN" : "DIS");
-       seq_printf(s, "pcie_irq_rx_count(%u)\n", priv->pcie_irq_rx_count);
-       status = reg &  PCIE_HDP_INT_RX_BITS;
-       seq_printf(s, "pcie_irq_rx_status(%s)\n",
-                  (status == PCIE_HDP_INT_RX_BITS) ? "EN" : "DIS");
-       seq_printf(s, "pcie_irq_uf_count(%u)\n", priv->pcie_irq_uf_count);
-       status = reg &  PCIE_HDP_INT_HHBM_UF;
-       seq_printf(s, "pcie_irq_hhbm_uf_status(%s)\n",
-                  (status == PCIE_HDP_INT_HHBM_UF) ? "EN" : "DIS");
-
-       return 0;
-}
-
-static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data)
-{
-       struct qtnf_bus *bus = dev_get_drvdata(s->private);
-       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
-
-       seq_printf(s, "tx_full_count(%u)\n", priv->tx_full_count);
-       seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count);
-       seq_printf(s, "tx_reclaim_done(%u)\n", priv->tx_reclaim_done);
-       seq_printf(s, "tx_reclaim_req(%u)\n", priv->tx_reclaim_req);
-
-       seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index);
-       seq_printf(s, "tx_bd_p_index(%u)\n",
-                  readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
-                       & (priv->tx_bd_num - 1));
-       seq_printf(s, "tx_bd_w_index(%u)\n", priv->tx_bd_w_index);
-       seq_printf(s, "tx queue len(%u)\n",
-                  CIRC_CNT(priv->tx_bd_w_index, priv->tx_bd_r_index,
-                           priv->tx_bd_num));
-
-       seq_printf(s, "rx_bd_r_index(%u)\n", priv->rx_bd_r_index);
-       seq_printf(s, "rx_bd_p_index(%u)\n",
-                  readl(PCIE_HDP_TX0DMA_CNT(priv->pcie_reg_base))
-                       & (priv->rx_bd_num - 1));
-       seq_printf(s, "rx_bd_w_index(%u)\n", priv->rx_bd_w_index);
-       seq_printf(s, "rx alloc queue len(%u)\n",
-                  CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
-                             priv->rx_bd_num));
-
-       return 0;
-}
-
-static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
-{
-       struct qtnf_bus *bus = dev_get_drvdata(s->private);
-       struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
-
-       seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n",
-                  priv->shm_ipc_ep_in.tx_packet_count);
-       seq_printf(s, "shm_ipc_ep_in.rx_packet_count(%zu)\n",
-                  priv->shm_ipc_ep_in.rx_packet_count);
-       seq_printf(s, "shm_ipc_ep_out.tx_packet_count(%zu)\n",
-                  priv->shm_ipc_ep_out.tx_timeout_count);
-       seq_printf(s, "shm_ipc_ep_out.rx_packet_count(%zu)\n",
-                  priv->shm_ipc_ep_out.rx_packet_count);
-
-       return 0;
-}
-
-static int qtnf_ep_fw_send(struct qtnf_pcie_bus_priv *priv, uint32_t size,
-                          int blk, const u8 *pblk, const u8 *fw)
-{
-       struct pci_dev *pdev = priv->pdev;
-       struct qtnf_bus *bus = pci_get_drvdata(pdev);
-
-       struct qtnf_pcie_fw_hdr *hdr;
-       u8 *pdata;
-
-       int hds = sizeof(*hdr);
-       struct sk_buff *skb = NULL;
-       int len = 0;
-       int ret;
-
-       skb = __dev_alloc_skb(QTN_PCIE_FW_BUFSZ, GFP_KERNEL);
-       if (!skb)
-               return -ENOMEM;
-
-       skb->len = QTN_PCIE_FW_BUFSZ;
-       skb->dev = NULL;
-
-       hdr = (struct qtnf_pcie_fw_hdr *)skb->data;
-       memcpy(hdr->boardflg, QTN_PCIE_BOARDFLG, strlen(QTN_PCIE_BOARDFLG));
-       hdr->fwsize = cpu_to_le32(size);
-       hdr->seqnum = cpu_to_le32(blk);
-
-       if (blk)
-               hdr->type = cpu_to_le32(QTN_FW_DSUB);
-       else
-               hdr->type = cpu_to_le32(QTN_FW_DBEGIN);
-
-       pdata = skb->data + hds;
-
-       len = QTN_PCIE_FW_BUFSZ - hds;
-       if (pblk >= (fw + size - len)) {
-               len = fw + size - pblk;
-               hdr->type = cpu_to_le32(QTN_FW_DEND);
-       }
-
-       hdr->pktlen = cpu_to_le32(len);
-       memcpy(pdata, pblk, len);
-       hdr->crc = cpu_to_le32(~crc32(0, pdata, len));
-
-       ret = qtnf_pcie_data_tx(bus, skb);
-
-       return (ret == NETDEV_TX_OK) ? len : 0;
-}
-
-static int
-qtnf_ep_fw_load(struct qtnf_pcie_bus_priv *priv, const u8 *fw, u32 fw_size)
-{
-       int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pcie_fw_hdr);
-       int blk_count = fw_size / blk_size + ((fw_size % blk_size) ? 1 : 0);
-       const u8 *pblk = fw;
-       int threshold = 0;
-       int blk = 0;
-       int len;
-
-       pr_debug("FW upload started: fw_addr=0x%p size=%d\n", fw, fw_size);
-
-       while (blk < blk_count) {
-               if (++threshold > 10000) {
-                       pr_err("FW upload failed: too many retries\n");
-                       return -ETIMEDOUT;
-               }
-
-               len = qtnf_ep_fw_send(priv, fw_size, blk, pblk, fw);
-               if (len <= 0)
-                       continue;
-
-               if (!((blk + 1) & QTN_PCIE_FW_DLMASK) ||
-                   (blk == (blk_count - 1))) {
-                       qtnf_set_state(&priv->bda->bda_rc_state,
-                                      QTN_RC_FW_SYNC);
-                       if (qtnf_poll_state(&priv->bda->bda_ep_state,
-                                           QTN_EP_FW_SYNC,
-                                           QTN_FW_DL_TIMEOUT_MS)) {
-                               pr_err("FW upload failed: SYNC timed out\n");
-                               return -ETIMEDOUT;
-                       }
-
-                       qtnf_clear_state(&priv->bda->bda_ep_state,
-                                        QTN_EP_FW_SYNC);
-
-                       if (qtnf_is_state(&priv->bda->bda_ep_state,
-                                         QTN_EP_FW_RETRY)) {
-                               if (blk == (blk_count - 1)) {
-                                       int last_round =
-                                               blk_count & QTN_PCIE_FW_DLMASK;
-                                       blk -= last_round;
-                                       pblk -= ((last_round - 1) *
-                                               blk_size + len);
-                               } else {
-                                       blk -= QTN_PCIE_FW_DLMASK;
-                                       pblk -= QTN_PCIE_FW_DLMASK * blk_size;
-                               }
-
-                               qtnf_clear_state(&priv->bda->bda_ep_state,
-                                                QTN_EP_FW_RETRY);
-
-                               pr_warn("FW upload retry: block #%d\n", blk);
-                               continue;
-                       }
-
-                       qtnf_pcie_data_tx_reclaim(priv);
-               }
-
-               pblk += len;
-               blk++;
-       }
-
-       pr_debug("FW upload completed: totally sent %d blocks\n", blk);
-       return 0;
-}
-
-static void qtnf_fw_work_handler(struct work_struct *work)
-{
-       struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work);
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       struct pci_dev *pdev = priv->pdev;
-       const struct firmware *fw;
-       int ret;
-       u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK;
-       const char *fwname = QTN_PCI_PEARL_FW_NAME;
-
-       if (flashboot) {
-               state |= QTN_RC_FW_FLASHBOOT;
-       } else {
-               ret = request_firmware(&fw, fwname, &pdev->dev);
-               if (ret < 0) {
-                       pr_err("failed to get firmware %s\n", fwname);
-                       goto fw_load_fail;
-               }
-       }
-
-       qtnf_set_state(&priv->bda->bda_rc_state, state);
-
-       if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY,
-                           QTN_FW_DL_TIMEOUT_MS)) {
-               pr_err("card is not ready\n");
-
-               if (!flashboot)
-                       release_firmware(fw);
-
-               goto fw_load_fail;
-       }
-
-       qtnf_clear_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY);
-
-       if (flashboot) {
-               pr_info("booting firmware from flash\n");
-       } else {
-               pr_info("starting firmware upload: %s\n", fwname);
-
-               ret = qtnf_ep_fw_load(priv, fw->data, fw->size);
-               release_firmware(fw);
-               if (ret) {
-                       pr_err("firmware upload error\n");
-                       goto fw_load_fail;
-               }
-       }
-
-       if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_DONE,
-                           QTN_FW_DL_TIMEOUT_MS)) {
-               pr_err("firmware bringup timed out\n");
-               goto fw_load_fail;
-       }
-
-       bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE;
-       pr_info("firmware is up and running\n");
-
-       if (qtnf_poll_state(&priv->bda->bda_ep_state,
-                           QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) {
-               pr_err("firmware runtime failure\n");
-               goto fw_load_fail;
-       }
-
-       ret = qtnf_core_attach(bus);
-       if (ret) {
-               pr_err("failed to attach core\n");
-               goto fw_load_fail;
-       }
-
-       qtnf_debugfs_init(bus, DRV_NAME);
-       qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show);
-       qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show);
-       qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats);
-       qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);
-       qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats);
-
-       goto fw_load_exit;
-
-fw_load_fail:
-       bus->fw_state = QTNF_FW_STATE_DETACHED;
-
-fw_load_exit:
-       complete(&bus->firmware_init_complete);
-       put_device(&pdev->dev);
-}
-
-static void qtnf_bringup_fw_async(struct qtnf_bus *bus)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
-       struct pci_dev *pdev = priv->pdev;
-
-       get_device(&pdev->dev);
-       INIT_WORK(&bus->fw_work, qtnf_fw_work_handler);
-       schedule_work(&bus->fw_work);
-}
-
-static void qtnf_reclaim_tasklet_fn(unsigned long data)
-{
-       struct qtnf_pcie_bus_priv *priv = (void *)data;
-
-       qtnf_pcie_data_tx_reclaim(priv);
-       qtnf_en_txdone_irq(priv);
-}
-
-static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       struct qtnf_pcie_bus_priv *pcie_priv;
-       struct qtnf_bus *bus;
-       int ret;
-
-       bus = devm_kzalloc(&pdev->dev,
-                          sizeof(*bus) + sizeof(*pcie_priv), GFP_KERNEL);
-       if (!bus)
-               return -ENOMEM;
-
-       pcie_priv = get_bus_priv(bus);
-
-       pci_set_drvdata(pdev, bus);
-       bus->bus_ops = &qtnf_pcie_bus_ops;
-       bus->dev = &pdev->dev;
-       bus->fw_state = QTNF_FW_STATE_RESET;
-       pcie_priv->pdev = pdev;
-
-       init_completion(&bus->firmware_init_complete);
-       mutex_init(&bus->bus_lock);
-       spin_lock_init(&pcie_priv->tx0_lock);
-       spin_lock_init(&pcie_priv->irq_lock);
-       spin_lock_init(&pcie_priv->tx_reclaim_lock);
-
-       /* init stats */
-       pcie_priv->tx_full_count = 0;
-       pcie_priv->tx_done_count = 0;
-       pcie_priv->pcie_irq_count = 0;
-       pcie_priv->pcie_irq_rx_count = 0;
-       pcie_priv->pcie_irq_tx_count = 0;
-       pcie_priv->pcie_irq_uf_count = 0;
-       pcie_priv->tx_reclaim_done = 0;
-       pcie_priv->tx_reclaim_req = 0;
-
-       tasklet_init(&pcie_priv->reclaim_tq, qtnf_reclaim_tasklet_fn,
-                    (unsigned long)pcie_priv);
-
-       init_dummy_netdev(&bus->mux_dev);
-       netif_napi_add(&bus->mux_dev, &bus->mux_napi,
-                      qtnf_rx_poll, 10);
-
-       pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE");
-       if (!pcie_priv->workqueue) {
-               pr_err("failed to alloc bus workqueue\n");
-               ret = -ENODEV;
-               goto err_init;
-       }
-
-       if (!pci_is_pcie(pdev)) {
-               pr_err("device %s is not PCI Express\n", pci_name(pdev));
-               ret = -EIO;
-               goto err_base;
-       }
-
-       qtnf_tune_pcie_mps(pcie_priv);
-
-       ret = pcim_enable_device(pdev);
-       if (ret) {
-               pr_err("failed to init PCI device %x\n", pdev->device);
-               goto err_base;
-       } else {
-               pr_debug("successful init of PCI device %x\n", pdev->device);
-       }
-
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-#else
-       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-#endif
-       if (ret) {
-               pr_err("PCIE DMA coherent mask init failed\n");
-               goto err_base;
-       }
-
-       pci_set_master(pdev);
-       qtnf_pcie_init_irq(pcie_priv);
-
-       ret = qtnf_pcie_init_memory(pcie_priv);
-       if (ret < 0) {
-               pr_err("PCIE memory init failed\n");
-               goto err_base;
-       }
-
-       pci_save_state(pdev);
-
-       ret = qtnf_pcie_init_shm_ipc(pcie_priv);
-       if (ret < 0) {
-               pr_err("PCIE SHM IPC init failed\n");
-               goto err_base;
-       }
-
-       ret = qtnf_pcie_init_xfer(pcie_priv);
-       if (ret) {
-               pr_err("PCIE xfer init failed\n");
-               goto err_ipc;
-       }
-
-       /* init default irq settings */
-       qtnf_init_hdp_irqs(pcie_priv);
-
-       /* start with disabled irqs */
-       qtnf_disable_hdp_irqs(pcie_priv);
-
-       ret = devm_request_irq(&pdev->dev, pdev->irq, &qtnf_interrupt, 0,
-                              "qtnf_pcie_irq", (void *)bus);
-       if (ret) {
-               pr_err("failed to request pcie irq %d\n", pdev->irq);
-               goto err_xfer;
-       }
-
-       qtnf_bringup_fw_async(bus);
-
-       return 0;
-
-err_xfer:
-       qtnf_free_xfer_buffers(pcie_priv);
-
-err_ipc:
-       qtnf_pcie_free_shm_ipc(pcie_priv);
-
-err_base:
-       flush_workqueue(pcie_priv->workqueue);
-       destroy_workqueue(pcie_priv->workqueue);
-       netif_napi_del(&bus->mux_napi);
-
-err_init:
-       tasklet_kill(&pcie_priv->reclaim_tq);
-       pci_set_drvdata(pdev, NULL);
-
-       return ret;
-}
-
-static void qtnf_pcie_remove(struct pci_dev *pdev)
-{
-       struct qtnf_pcie_bus_priv *priv;
-       struct qtnf_bus *bus;
-
-       bus = pci_get_drvdata(pdev);
-       if (!bus)
-               return;
-
-       wait_for_completion(&bus->firmware_init_complete);
-
-       if (bus->fw_state == QTNF_FW_STATE_ACTIVE ||
-           bus->fw_state == QTNF_FW_STATE_EP_DEAD)
-               qtnf_core_detach(bus);
-
-       priv = get_bus_priv(bus);
-
-       netif_napi_del(&bus->mux_napi);
-       flush_workqueue(priv->workqueue);
-       destroy_workqueue(priv->workqueue);
-       tasklet_kill(&priv->reclaim_tq);
-
-       qtnf_free_xfer_buffers(priv);
-       qtnf_debugfs_remove(bus);
-
-       qtnf_pcie_free_shm_ipc(priv);
-       qtnf_reset_card(priv);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int qtnf_pcie_suspend(struct device *dev)
-{
-       return -EOPNOTSUPP;
-}
-
-static int qtnf_pcie_resume(struct device *dev)
-{
-       return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-#ifdef CONFIG_PM_SLEEP
-/* Power Management Hooks */
-static SIMPLE_DEV_PM_OPS(qtnf_pcie_pm_ops, qtnf_pcie_suspend,
-                        qtnf_pcie_resume);
-#endif
-
-static const struct pci_device_id qtnf_pcie_devid_table[] = {
-       {
-               PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QTN_PEARL,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-       },
-       { },
-};
-
-MODULE_DEVICE_TABLE(pci, qtnf_pcie_devid_table);
-
-static struct pci_driver qtnf_pcie_drv_data = {
-       .name = DRV_NAME,
-       .id_table = qtnf_pcie_devid_table,
-       .probe = qtnf_pcie_probe,
-       .remove = qtnf_pcie_remove,
-#ifdef CONFIG_PM_SLEEP
-       .driver = {
-               .pm = &qtnf_pcie_pm_ops,
-       },
-#endif
-};
-
-static int __init qtnf_pcie_register(void)
-{
-       pr_info("register Quantenna QSR10g FullMAC PCIE driver\n");
-       return pci_register_driver(&qtnf_pcie_drv_data);
-}
-
-static void __exit qtnf_pcie_exit(void)
-{
-       pr_info("unregister Quantenna QSR10g FullMAC PCIE driver\n");
-       pci_unregister_driver(&qtnf_pcie_drv_data);
-}
-
-module_init(qtnf_pcie_register);
-module_exit(qtnf_pcie_exit);
-
-MODULE_AUTHOR("Quantenna Communications");
-MODULE_DESCRIPTION("Quantenna QSR10g PCIe bus driver for 802.11 wireless LAN.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h
deleted file mode 100644 (file)
index 397875a..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2015-2016 Quantenna Communications, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _QTN_FMAC_PCIE_H_
-#define _QTN_FMAC_PCIE_H_
-
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-
-#include "pcie_regs_pearl.h"
-#include "pcie_ipc.h"
-#include "shm_ipc.h"
-
-struct bus;
-
-struct qtnf_pcie_bus_priv {
-       struct pci_dev  *pdev;
-
-       /* lock for irq configuration changes */
-       spinlock_t irq_lock;
-
-       /* lock for tx reclaim operations */
-       spinlock_t tx_reclaim_lock;
-       /* lock for tx0 operations */
-       spinlock_t tx0_lock;
-       u8 msi_enabled;
-       u8 tx_stopped;
-       int mps;
-
-       struct workqueue_struct *workqueue;
-       struct tasklet_struct reclaim_tq;
-
-       void __iomem *sysctl_bar;
-       void __iomem *epmem_bar;
-       void __iomem *dmareg_bar;
-
-       struct qtnf_shm_ipc shm_ipc_ep_in;
-       struct qtnf_shm_ipc shm_ipc_ep_out;
-
-       struct qtnf_pcie_bda __iomem *bda;
-       void __iomem *pcie_reg_base;
-
-       u16 tx_bd_num;
-       u16 rx_bd_num;
-
-       struct sk_buff **tx_skb;
-       struct sk_buff **rx_skb;
-
-       struct qtnf_tx_bd *tx_bd_vbase;
-       dma_addr_t tx_bd_pbase;
-
-       struct qtnf_rx_bd *rx_bd_vbase;
-       dma_addr_t rx_bd_pbase;
-
-       dma_addr_t bd_table_paddr;
-       void *bd_table_vaddr;
-       u32 bd_table_len;
-
-       u32 rx_bd_w_index;
-       u32 rx_bd_r_index;
-
-       u32 tx_bd_w_index;
-       u32 tx_bd_r_index;
-
-       u32 pcie_irq_mask;
-
-       /* diagnostics stats */
-       u32 pcie_irq_count;
-       u32 pcie_irq_rx_count;
-       u32 pcie_irq_tx_count;
-       u32 pcie_irq_uf_count;
-       u32 tx_full_count;
-       u32 tx_done_count;
-       u32 tx_reclaim_done;
-       u32 tx_reclaim_req;
-};
-
-#endif /* _QTN_FMAC_PCIE_H_ */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h
deleted file mode 100644 (file)
index 00bb21a..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2015-2016 Quantenna Communications, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _QTN_FMAC_PCIE_IPC_H_
-#define _QTN_FMAC_PCIE_IPC_H_
-
-#include <linux/types.h>
-
-#include "shm_ipc_defs.h"
-
-/* bitmap for EP status and flags: updated by EP, read by RC */
-#define QTN_EP_HAS_UBOOT       BIT(0)
-#define QTN_EP_HAS_FIRMWARE    BIT(1)
-#define QTN_EP_REQ_UBOOT       BIT(2)
-#define QTN_EP_REQ_FIRMWARE    BIT(3)
-#define QTN_EP_ERROR_UBOOT     BIT(4)
-#define QTN_EP_ERROR_FIRMWARE  BIT(5)
-
-#define QTN_EP_FW_LOADRDY      BIT(8)
-#define QTN_EP_FW_SYNC         BIT(9)
-#define QTN_EP_FW_RETRY                BIT(10)
-#define QTN_EP_FW_QLINK_DONE   BIT(15)
-#define QTN_EP_FW_DONE         BIT(16)
-
-/* bitmap for RC status and flags: updated by RC, read by EP */
-#define QTN_RC_PCIE_LINK       BIT(0)
-#define QTN_RC_NET_LINK                BIT(1)
-#define QTN_RC_FW_FLASHBOOT    BIT(5)
-#define QTN_RC_FW_QLINK                BIT(7)
-#define QTN_RC_FW_LOADRDY      BIT(8)
-#define QTN_RC_FW_SYNC         BIT(9)
-
-/* state transition timeouts */
-#define QTN_FW_DL_TIMEOUT_MS   3000
-#define QTN_FW_QLINK_TIMEOUT_MS        30000
-#define QTN_EP_RESET_WAIT_MS   1000
-
-#define PCIE_HDP_INT_RX_BITS (0                \
-       | PCIE_HDP_INT_EP_TXDMA         \
-       | PCIE_HDP_INT_EP_TXEMPTY       \
-       | PCIE_HDP_INT_HHBM_UF          \
-       )
-
-#define PCIE_HDP_INT_TX_BITS (0                \
-       | PCIE_HDP_INT_EP_RXDMA         \
-       )
-
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-#define QTN_HOST_HI32(a)       ((u32)(((u64)a) >> 32))
-#define QTN_HOST_LO32(a)       ((u32)(((u64)a) & 0xffffffffUL))
-#define QTN_HOST_ADDR(h, l)    ((((u64)h) << 32) | ((u64)l))
-#else
-#define QTN_HOST_HI32(a)       0
-#define QTN_HOST_LO32(a)       ((u32)(((u32)a) & 0xffffffffUL))
-#define QTN_HOST_ADDR(h, l)    ((u32)l)
-#endif
-
-#define QTN_SYSCTL_BAR 0
-#define QTN_SHMEM_BAR  2
-#define QTN_DMA_BAR    3
-
-#define QTN_PCIE_BDA_VERSION           0x1002
-
-#define PCIE_BDA_NAMELEN               32
-#define PCIE_HHBM_MAX_SIZE             2048
-
-#define SKB_BUF_SIZE           2048
-
-#define QTN_PCIE_BOARDFLG      "PCIEQTN"
-#define QTN_PCIE_FW_DLMASK     0xF
-#define QTN_PCIE_FW_BUFSZ      2048
-
-#define QTN_ENET_ADDR_LENGTH   6
-
-#define QTN_TXDONE_MASK                ((u32)0x80000000)
-#define QTN_GET_LEN(x)         ((x) & 0xFFFF)
-
-#define QTN_PCIE_TX_DESC_LEN_MASK      0xFFFF
-#define QTN_PCIE_TX_DESC_LEN_SHIFT     0
-#define QTN_PCIE_TX_DESC_PORT_MASK     0xF
-#define QTN_PCIE_TX_DESC_PORT_SHIFT    16
-#define QTN_PCIE_TX_DESC_TQE_BIT       BIT(24)
-
-#define QTN_EP_LHOST_TQE_PORT  4
-
-enum qtnf_pcie_bda_ipc_flags {
-       QTN_PCIE_IPC_FLAG_HBM_MAGIC     = BIT(0),
-       QTN_PCIE_IPC_FLAG_SHM_PIO       = BIT(1),
-};
-
-struct qtnf_pcie_bda {
-       __le16 bda_len;
-       __le16 bda_version;
-       __le32 bda_pci_endian;
-       __le32 bda_ep_state;
-       __le32 bda_rc_state;
-       __le32 bda_dma_mask;
-       __le32 bda_msi_addr;
-       __le32 bda_flashsz;
-       u8 bda_boardname[PCIE_BDA_NAMELEN];
-       __le32 bda_rc_msi_enabled;
-       u8 bda_hhbm_list[PCIE_HHBM_MAX_SIZE];
-       __le32 bda_dsbw_start_index;
-       __le32 bda_dsbw_end_index;
-       __le32 bda_dsbw_total_bytes;
-       __le32 bda_rc_tx_bd_base;
-       __le32 bda_rc_tx_bd_num;
-       u8 bda_pcie_mac[QTN_ENET_ADDR_LENGTH];
-       struct qtnf_shm_ipc_region bda_shm_reg1 __aligned(4096); /* host TX */
-       struct qtnf_shm_ipc_region bda_shm_reg2 __aligned(4096); /* host RX */
-} __packed;
-
-struct qtnf_tx_bd {
-       __le32 addr;
-       __le32 addr_h;
-       __le32 info;
-       __le32 info_h;
-} __packed;
-
-struct qtnf_rx_bd {
-       __le32 addr;
-       __le32 addr_h;
-       __le32 info;
-       __le32 info_h;
-       __le32 next_ptr;
-       __le32 next_ptr_h;
-} __packed;
-
-enum qtnf_fw_loadtype {
-       QTN_FW_DBEGIN,
-       QTN_FW_DSUB,
-       QTN_FW_DEND,
-       QTN_FW_CTRL
-};
-
-struct qtnf_pcie_fw_hdr {
-       u8 boardflg[8];
-       __le32 fwsize;
-       __le32 seqnum;
-       __le32 type;
-       __le32 pktlen;
-       __le32 crc;
-} __packed;
-
-#endif /* _QTN_FMAC_PCIE_IPC_H_ */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h
deleted file mode 100644 (file)
index 0bfe285..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2015 Quantenna Communications, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __PEARL_PCIE_H
-#define __PEARL_PCIE_H
-
-#define        PCIE_GEN2_BASE                          (0xe9000000)
-#define        PCIE_GEN3_BASE                          (0xe7000000)
-
-#define PEARL_CUR_PCIE_BASE                    (PCIE_GEN2_BASE)
-#define PCIE_HDP_OFFSET                                (0x2000)
-
-#define PCIE_HDP_CTRL(base)                    ((base) + 0x2c00)
-#define PCIE_HDP_AXI_CTRL(base)                        ((base) + 0x2c04)
-#define PCIE_HDP_HOST_WR_DESC0(base)           ((base) + 0x2c10)
-#define PCIE_HDP_HOST_WR_DESC0_H(base)         ((base) + 0x2c14)
-#define PCIE_HDP_HOST_WR_DESC1(base)           ((base) + 0x2c18)
-#define PCIE_HDP_HOST_WR_DESC1_H(base)         ((base) + 0x2c1c)
-#define PCIE_HDP_HOST_WR_DESC2(base)           ((base) + 0x2c20)
-#define PCIE_HDP_HOST_WR_DESC2_H(base)         ((base) + 0x2c24)
-#define PCIE_HDP_HOST_WR_DESC3(base)           ((base) + 0x2c28)
-#define PCIE_HDP_HOST_WR_DESC4_H(base)         ((base) + 0x2c2c)
-#define PCIE_HDP_RX_INT_CTRL(base)             ((base) + 0x2c30)
-#define PCIE_HDP_TX_INT_CTRL(base)             ((base) + 0x2c34)
-#define PCIE_HDP_INT_STATUS(base)              ((base) + 0x2c38)
-#define PCIE_HDP_INT_EN(base)                  ((base) + 0x2c3c)
-#define PCIE_HDP_RX_DESC0_PTR(base)            ((base) + 0x2c40)
-#define PCIE_HDP_RX_DESC0_NOE(base)            ((base) + 0x2c44)
-#define PCIE_HDP_RX_DESC1_PTR(base)            ((base) + 0x2c48)
-#define PCIE_HDP_RX_DESC1_NOE(base)            ((base) + 0x2c4c)
-#define PCIE_HDP_RX_DESC2_PTR(base)            ((base) + 0x2c50)
-#define PCIE_HDP_RX_DESC2_NOE(base)            ((base) + 0x2c54)
-#define PCIE_HDP_RX_DESC3_PTR(base)            ((base) + 0x2c58)
-#define PCIE_HDP_RX_DESC3_NOE(base)            ((base) + 0x2c5c)
-
-#define PCIE_HDP_TX0_BASE_ADDR(base)           ((base) + 0x2c60)
-#define PCIE_HDP_TX1_BASE_ADDR(base)           ((base) + 0x2c64)
-#define PCIE_HDP_TX0_Q_CTRL(base)              ((base) + 0x2c70)
-#define PCIE_HDP_TX1_Q_CTRL(base)              ((base) + 0x2c74)
-#define PCIE_HDP_CFG0(base)                    ((base) + 0x2c80)
-#define PCIE_HDP_CFG1(base)                    ((base) + 0x2c84)
-#define PCIE_HDP_CFG2(base)                    ((base) + 0x2c88)
-#define PCIE_HDP_CFG3(base)                    ((base) + 0x2c8c)
-#define PCIE_HDP_CFG4(base)                    ((base) + 0x2c90)
-#define PCIE_HDP_CFG5(base)                    ((base) + 0x2c94)
-#define PCIE_HDP_CFG6(base)                    ((base) + 0x2c98)
-#define PCIE_HDP_CFG7(base)                    ((base) + 0x2c9c)
-#define PCIE_HDP_CFG8(base)                    ((base) + 0x2ca0)
-#define PCIE_HDP_CFG9(base)                    ((base) + 0x2ca4)
-#define PCIE_HDP_CFG10(base)                   ((base) + 0x2ca8)
-#define PCIE_HDP_CFG11(base)                   ((base) + 0x2cac)
-#define PCIE_INT(base)                         ((base) + 0x2cb0)
-#define PCIE_INT_MASK(base)                    ((base) + 0x2cb4)
-#define PCIE_MSI_MASK(base)                    ((base) + 0x2cb8)
-#define PCIE_MSI_PNDG(base)                    ((base) + 0x2cbc)
-#define PCIE_PRI_CFG(base)                     ((base) + 0x2cc0)
-#define PCIE_PHY_CR(base)                      ((base) + 0x2cc4)
-#define PCIE_HDP_CTAG_CTRL(base)               ((base) + 0x2cf4)
-#define PCIE_HDP_HHBM_BUF_PTR(base)            ((base) + 0x2d00)
-#define PCIE_HDP_HHBM_BUF_PTR_H(base)          ((base) + 0x2d04)
-#define PCIE_HDP_HHBM_BUF_FIFO_NOE(base)       ((base) + 0x2d04)
-#define PCIE_HDP_RX0DMA_CNT(base)              ((base) + 0x2d10)
-#define PCIE_HDP_RX1DMA_CNT(base)              ((base) + 0x2d14)
-#define PCIE_HDP_RX2DMA_CNT(base)              ((base) + 0x2d18)
-#define PCIE_HDP_RX3DMA_CNT(base)              ((base) + 0x2d1c)
-#define PCIE_HDP_TX0DMA_CNT(base)              ((base) + 0x2d20)
-#define PCIE_HDP_TX1DMA_CNT(base)              ((base) + 0x2d24)
-#define PCIE_HDP_RXDMA_CTRL(base)              ((base) + 0x2d28)
-#define PCIE_HDP_TX_HOST_Q_SZ_CTRL(base)       ((base) + 0x2d2c)
-#define PCIE_HDP_TX_HOST_Q_BASE_L(base)                ((base) + 0x2d30)
-#define PCIE_HDP_TX_HOST_Q_BASE_H(base)                ((base) + 0x2d34)
-#define PCIE_HDP_TX_HOST_Q_WR_PTR(base)                ((base) + 0x2d38)
-#define PCIE_HDP_TX_HOST_Q_RD_PTR(base)                ((base) + 0x2d3c)
-#define PCIE_HDP_TX_HOST_Q_STS(base)           ((base) + 0x2d40)
-
-/* Host HBM pool registers */
-#define PCIE_HHBM_CSR_REG(base)                        ((base) + 0x2e00)
-#define PCIE_HHBM_Q_BASE_REG(base)             ((base) + 0x2e04)
-#define PCIE_HHBM_Q_LIMIT_REG(base)            ((base) + 0x2e08)
-#define PCIE_HHBM_Q_WR_REG(base)               ((base) + 0x2e0c)
-#define PCIE_HHBM_Q_RD_REG(base)               ((base) + 0x2e10)
-#define PCIE_HHBM_POOL_DATA_0_H(base)          ((base) + 0x2e90)
-#define PCIE_HHBM_CONFIG(base)                 ((base) + 0x2f9c)
-#define PCIE_HHBM_POOL_REQ_0(base)             ((base) + 0x2f10)
-#define PCIE_HHBM_POOL_DATA_0(base)            ((base) + 0x2f40)
-#define PCIE_HHBM_WATERMARK_MASKED_INT(base)   ((base) + 0x2f68)
-#define PCIE_HHBM_WATERMARK_INT(base)          ((base) + 0x2f6c)
-#define PCIE_HHBM_POOL_WATERMARK(base)         ((base) + 0x2f70)
-#define PCIE_HHBM_POOL_OVERFLOW_CNT(base)      ((base) + 0x2f90)
-#define PCIE_HHBM_POOL_UNDERFLOW_CNT(base)     ((base) + 0x2f94)
-#define HBM_INT_STATUS(base)                   ((base) + 0x2f9c)
-#define PCIE_HHBM_POOL_CNFIG(base)             ((base) + 0x2f9c)
-
-/* host HBM bit field definition */
-#define HHBM_CONFIG_SOFT_RESET                 (BIT(8))
-#define HHBM_WR_REQ                            (BIT(0))
-#define HHBM_RD_REQ                            (BIT(1))
-#define HHBM_DONE                              (BIT(31))
-#define HHBM_64BIT                             (BIT(10))
-
-/* offsets for dual PCIE */
-#define PCIE_PORT_LINK_CTL(base)               ((base) + 0x0710)
-#define PCIE_GEN2_CTL(base)                    ((base) + 0x080C)
-#define PCIE_GEN3_OFF(base)                    ((base) + 0x0890)
-#define PCIE_ATU_CTRL1(base)                   ((base) + 0x0904)
-#define PCIE_ATU_CTRL2(base)                   ((base) + 0x0908)
-#define PCIE_ATU_BASE_LOW(base)                        ((base) + 0x090C)
-#define PCIE_ATU_BASE_HIGH(base)               ((base) + 0x0910)
-#define PCIE_ATU_BASE_LIMIT(base)              ((base) + 0x0914)
-#define PCIE_ATU_TGT_LOW(base)                 ((base) + 0x0918)
-#define PCIE_ATU_TGT_HIGH(base)                        ((base) + 0x091C)
-#define PCIE_DMA_WR_ENABLE(base)               ((base) + 0x097C)
-#define PCIE_DMA_WR_CHWTLOW(base)              ((base) + 0x0988)
-#define PCIE_DMA_WR_CHWTHIG(base)              ((base) + 0x098C)
-#define PCIE_DMA_WR_INTSTS(base)               ((base) + 0x09BC)
-#define PCIE_DMA_WR_INTMASK(base)              ((base) + 0x09C4)
-#define PCIE_DMA_WR_INTCLER(base)              ((base) + 0x09C8)
-#define PCIE_DMA_WR_DONE_IMWR_ADDR_L(base)     ((base) + 0x09D0)
-#define PCIE_DMA_WR_DONE_IMWR_ADDR_H(base)     ((base) + 0x09D4)
-#define PCIE_DMA_WR_ABORT_IMWR_ADDR_L(base)    ((base) + 0x09D8)
-#define PCIE_DMA_WR_ABORT_IMWR_ADDR_H(base)    ((base) + 0x09DC)
-#define PCIE_DMA_WR_IMWR_DATA(base)            ((base) + 0x09E0)
-#define PCIE_DMA_WR_LL_ERR_EN(base)            ((base) + 0x0A00)
-#define PCIE_DMA_WR_DOORBELL(base)             ((base) + 0x0980)
-#define PCIE_DMA_RD_ENABLE(base)               ((base) + 0x099C)
-#define PCIE_DMA_RD_DOORBELL(base)             ((base) + 0x09A0)
-#define PCIE_DMA_RD_CHWTLOW(base)              ((base) + 0x09A8)
-#define PCIE_DMA_RD_CHWTHIG(base)              ((base) + 0x09AC)
-#define PCIE_DMA_RD_INTSTS(base)               ((base) + 0x0A10)
-#define PCIE_DMA_RD_INTMASK(base)              ((base) + 0x0A18)
-#define PCIE_DMA_RD_INTCLER(base)              ((base) + 0x0A1C)
-#define PCIE_DMA_RD_ERR_STS_L(base)            ((base) + 0x0A24)
-#define PCIE_DMA_RD_ERR_STS_H(base)            ((base) + 0x0A28)
-#define PCIE_DMA_RD_LL_ERR_EN(base)            ((base) + 0x0A34)
-#define PCIE_DMA_RD_DONE_IMWR_ADDR_L(base)     ((base) + 0x0A3C)
-#define PCIE_DMA_RD_DONE_IMWR_ADDR_H(base)     ((base) + 0x0A40)
-#define PCIE_DMA_RD_ABORT_IMWR_ADDR_L(base)    ((base) + 0x0A44)
-#define PCIE_DMA_RD_ABORT_IMWR_ADDR_H(base)    ((base) + 0x0A48)
-#define PCIE_DMA_RD_IMWR_DATA(base)            ((base) + 0x0A4C)
-#define PCIE_DMA_CHNL_CONTEXT(base)            ((base) + 0x0A6C)
-#define PCIE_DMA_CHNL_CNTRL(base)              ((base) + 0x0A70)
-#define PCIE_DMA_XFR_SIZE(base)                        ((base) + 0x0A78)
-#define PCIE_DMA_SAR_LOW(base)                 ((base) + 0x0A7C)
-#define PCIE_DMA_SAR_HIGH(base)                        ((base) + 0x0A80)
-#define PCIE_DMA_DAR_LOW(base)                 ((base) + 0x0A84)
-#define PCIE_DMA_DAR_HIGH(base)                        ((base) + 0x0A88)
-#define PCIE_DMA_LLPTR_LOW(base)               ((base) + 0x0A8C)
-#define PCIE_DMA_LLPTR_HIGH(base)              ((base) + 0x0A90)
-#define PCIE_DMA_WRLL_ERR_ENB(base)            ((base) + 0x0A00)
-#define PCIE_DMA_RDLL_ERR_ENB(base)            ((base) + 0x0A34)
-#define PCIE_DMABD_CHNL_CNTRL(base)            ((base) + 0x8000)
-#define PCIE_DMABD_XFR_SIZE(base)              ((base) + 0x8004)
-#define PCIE_DMABD_SAR_LOW(base)               ((base) + 0x8008)
-#define PCIE_DMABD_SAR_HIGH(base)              ((base) + 0x800c)
-#define PCIE_DMABD_DAR_LOW(base)               ((base) + 0x8010)
-#define PCIE_DMABD_DAR_HIGH(base)              ((base) + 0x8014)
-#define PCIE_DMABD_LLPTR_LOW(base)             ((base) + 0x8018)
-#define PCIE_DMABD_LLPTR_HIGH(base)            ((base) + 0x801c)
-#define PCIE_WRDMA0_CHNL_CNTRL(base)           ((base) + 0x8000)
-#define PCIE_WRDMA0_XFR_SIZE(base)             ((base) + 0x8004)
-#define PCIE_WRDMA0_SAR_LOW(base)              ((base) + 0x8008)
-#define PCIE_WRDMA0_SAR_HIGH(base)             ((base) + 0x800c)
-#define PCIE_WRDMA0_DAR_LOW(base)              ((base) + 0x8010)
-#define PCIE_WRDMA0_DAR_HIGH(base)             ((base) + 0x8014)
-#define PCIE_WRDMA0_LLPTR_LOW(base)            ((base) + 0x8018)
-#define PCIE_WRDMA0_LLPTR_HIGH(base)           ((base) + 0x801c)
-#define PCIE_WRDMA1_CHNL_CNTRL(base)           ((base) + 0x8020)
-#define PCIE_WRDMA1_XFR_SIZE(base)             ((base) + 0x8024)
-#define PCIE_WRDMA1_SAR_LOW(base)              ((base) + 0x8028)
-#define PCIE_WRDMA1_SAR_HIGH(base)             ((base) + 0x802c)
-#define PCIE_WRDMA1_DAR_LOW(base)              ((base) + 0x8030)
-#define PCIE_WRDMA1_DAR_HIGH(base)             ((base) + 0x8034)
-#define PCIE_WRDMA1_LLPTR_LOW(base)            ((base) + 0x8038)
-#define PCIE_WRDMA1_LLPTR_HIGH(base)           ((base) + 0x803c)
-#define PCIE_RDDMA0_CHNL_CNTRL(base)           ((base) + 0x8040)
-#define PCIE_RDDMA0_XFR_SIZE(base)             ((base) + 0x8044)
-#define PCIE_RDDMA0_SAR_LOW(base)              ((base) + 0x8048)
-#define PCIE_RDDMA0_SAR_HIGH(base)             ((base) + 0x804c)
-#define PCIE_RDDMA0_DAR_LOW(base)              ((base) + 0x8050)
-#define PCIE_RDDMA0_DAR_HIGH(base)             ((base) + 0x8054)
-#define PCIE_RDDMA0_LLPTR_LOW(base)            ((base) + 0x8058)
-#define PCIE_RDDMA0_LLPTR_HIGH(base)           ((base) + 0x805c)
-#define PCIE_RDDMA1_CHNL_CNTRL(base)           ((base) + 0x8060)
-#define PCIE_RDDMA1_XFR_SIZE(base)             ((base) + 0x8064)
-#define PCIE_RDDMA1_SAR_LOW(base)              ((base) + 0x8068)
-#define PCIE_RDDMA1_SAR_HIGH(base)             ((base) + 0x806c)
-#define PCIE_RDDMA1_DAR_LOW(base)              ((base) + 0x8070)
-#define PCIE_RDDMA1_DAR_HIGH(base)             ((base) + 0x8074)
-#define PCIE_RDDMA1_LLPTR_LOW(base)            ((base) + 0x8078)
-#define PCIE_RDDMA1_LLPTR_HIGH(base)           ((base) + 0x807c)
-
-#define PCIE_ID(base)                          ((base) + 0x0000)
-#define PCIE_CMD(base)                         ((base) + 0x0004)
-#define PCIE_BAR(base, n)                      ((base) + 0x0010 + ((n) << 2))
-#define PCIE_CAP_PTR(base)                     ((base) + 0x0034)
-#define PCIE_MSI_LBAR(base)                    ((base) + 0x0054)
-#define PCIE_MSI_CTRL(base)                    ((base) + 0x0050)
-#define PCIE_MSI_ADDR_L(base)                  ((base) + 0x0054)
-#define PCIE_MSI_ADDR_H(base)                  ((base) + 0x0058)
-#define PCIE_MSI_DATA(base)                    ((base) + 0x005C)
-#define PCIE_MSI_MASK_BIT(base)                        ((base) + 0x0060)
-#define PCIE_MSI_PEND_BIT(base)                        ((base) + 0x0064)
-#define PCIE_DEVCAP(base)                      ((base) + 0x0074)
-#define PCIE_DEVCTLSTS(base)                   ((base) + 0x0078)
-
-#define PCIE_CMDSTS(base)                      ((base) + 0x0004)
-#define PCIE_LINK_STAT(base)                   ((base) + 0x80)
-#define PCIE_LINK_CTL2(base)                   ((base) + 0xa0)
-#define PCIE_ASPM_L1_CTRL(base)                        ((base) + 0x70c)
-#define PCIE_ASPM_LINK_CTRL(base)              (PCIE_LINK_STAT)
-#define PCIE_ASPM_L1_SUBSTATE_TIMING(base)     ((base) + 0xB44)
-#define PCIE_L1SUB_CTRL1(base)                 ((base) + 0x150)
-#define PCIE_PMCSR(base)                       ((base) + 0x44)
-#define PCIE_CFG_SPACE_LIMIT(base)             ((base) + 0x100)
-
-/* PCIe link defines */
-#define PEARL_PCIE_LINKUP                      (0x7)
-#define PEARL_PCIE_DATA_LINK                   (BIT(0))
-#define PEARL_PCIE_PHY_LINK                    (BIT(1))
-#define PEARL_PCIE_LINK_RST                    (BIT(3))
-#define PEARL_PCIE_FATAL_ERR                   (BIT(5))
-#define PEARL_PCIE_NONFATAL_ERR                        (BIT(6))
-
-/* PCIe Lane defines */
-#define PCIE_G2_LANE_X1                                ((BIT(0)) << 16)
-#define PCIE_G2_LANE_X2                                ((BIT(0) | BIT(1)) << 16)
-
-/* PCIe DLL link enable */
-#define PCIE_DLL_LINK_EN                       ((BIT(0)) << 5)
-
-#define PCIE_LINK_GEN1                         (BIT(0))
-#define PCIE_LINK_GEN2                         (BIT(1))
-#define PCIE_LINK_GEN3                         (BIT(2))
-#define PCIE_LINK_MODE(x)                      (((x) >> 16) & 0x7)
-
-#define MSI_EN                                 (BIT(0))
-#define MSI_64_EN                              (BIT(7))
-#define PCIE_MSI_ADDR_OFFSET(a)                        ((a) & 0xFFFF)
-#define PCIE_MSI_ADDR_ALIGN(a)                 ((a) & (~0xFFFF))
-
-#define PCIE_BAR_MASK(base, n)                 ((base) + 0x1010 + ((n) << 2))
-#define PCIE_MAX_BAR                           (6)
-
-#define PCIE_ATU_VIEW(base)                    ((base) + 0x0900)
-#define PCIE_ATU_CTL1(base)                    ((base) + 0x0904)
-#define PCIE_ATU_CTL2(base)                    ((base) + 0x0908)
-#define PCIE_ATU_LBAR(base)                    ((base) + 0x090c)
-#define PCIE_ATU_UBAR(base)                    ((base) + 0x0910)
-#define PCIE_ATU_LAR(base)                     ((base) + 0x0914)
-#define PCIE_ATU_LTAR(base)                    ((base) + 0x0918)
-#define PCIE_ATU_UTAR(base)                    ((base) + 0x091c)
-
-#define PCIE_MSI_ADDR_LOWER(base)              ((base) + 0x0820)
-#define PCIE_MSI_ADDR_UPPER(base)              ((base) + 0x0824)
-#define PCIE_MSI_ENABLE(base)                  ((base) + 0x0828)
-#define PCIE_MSI_MASK_RC(base)                 ((base) + 0x082c)
-#define PCIE_MSI_STATUS(base)                  ((base) + 0x0830)
-#define PEARL_PCIE_MSI_REGION                  (0xce000000)
-#define PEARL_PCIE_MSI_DATA                    (0)
-#define PCIE_MSI_GPIO(base)                    ((base) + 0x0888)
-
-#define PCIE_HDP_HOST_QUEUE_FULL       (BIT(17))
-#define USE_BAR_MATCH_MODE
-#define PCIE_ATU_OB_REGION             (BIT(0))
-#define PCIE_ATU_EN_REGION             (BIT(31))
-#define PCIE_ATU_EN_MATCH              (BIT(30))
-#define PCIE_BASE_REGION               (0xb0000000)
-#define PCIE_MEM_MAP_SIZE              (512 * 1024)
-
-#define PCIE_OB_REG_REGION             (0xcf000000)
-#define PCIE_CONFIG_REGION             (0xcf000000)
-#define PCIE_CONFIG_SIZE               (4096)
-#define PCIE_CONFIG_CH                 (1)
-
-/* inbound mapping */
-#define PCIE_IB_BAR0                   (0x00000000)    /* ddr */
-#define PCIE_IB_BAR0_CH                        (0)
-#define PCIE_IB_BAR3                   (0xe0000000)    /* sys_reg */
-#define PCIE_IB_BAR3_CH                        (1)
-
-/* outbound mapping */
-#define PCIE_MEM_CH                    (0)
-#define PCIE_REG_CH                    (1)
-#define PCIE_MEM_REGION                        (0xc0000000)
-#define        PCIE_MEM_SIZE                   (0x000fffff)
-#define PCIE_MEM_TAR                   (0x80000000)
-
-#define PCIE_MSI_REGION                        (0xce000000)
-#define PCIE_MSI_SIZE                  (KBYTE(4) - 1)
-#define PCIE_MSI_CH                    (1)
-
-/* size of config region */
-#define PCIE_CFG_SIZE                  (0x0000ffff)
-
-#define PCIE_ATU_DIR_IB                        (BIT(31))
-#define PCIE_ATU_DIR_OB                        (0)
-#define PCIE_ATU_DIR_CFG               (2)
-#define PCIE_ATU_DIR_MATCH_IB          (BIT(31) | BIT(30))
-
-#define PCIE_DMA_WR_0                  (0)
-#define PCIE_DMA_WR_1                  (1)
-#define PCIE_DMA_RD_0                  (2)
-#define PCIE_DMA_RD_1                  (3)
-
-#define PCIE_DMA_CHNL_CNTRL_CB         (BIT(0))
-#define PCIE_DMA_CHNL_CNTRL_TCB                (BIT(1))
-#define PCIE_DMA_CHNL_CNTRL_LLP                (BIT(2))
-#define PCIE_DMA_CHNL_CNTRL_LIE                (BIT(3))
-#define PCIE_DMA_CHNL_CNTRL_RIE                (BIT(4))
-#define PCIE_DMA_CHNL_CNTRL_CSS                (BIT(8))
-#define PCIE_DMA_CHNL_CNTRL_LLE                (BIT(9))
-#define PCIE_DMA_CHNL_CNTRL_TLP                (BIT(26))
-
-#define PCIE_DMA_CHNL_CONTEXT_RD       (BIT(31))
-#define PCIE_DMA_CHNL_CONTEXT_WR       (0)
-#define PCIE_MAX_BAR                   (6)
-
-/* PCIe HDP interrupt status definition */
-#define PCIE_HDP_INT_EP_RXDMA          (BIT(0))
-#define PCIE_HDP_INT_HBM_UF            (BIT(1))
-#define PCIE_HDP_INT_RX_LEN_ERR                (BIT(2))
-#define PCIE_HDP_INT_RX_HDR_LEN_ERR    (BIT(3))
-#define PCIE_HDP_INT_EP_TXDMA          (BIT(12))
-#define PCIE_HDP_INT_HHBM_UF           (BIT(13))
-#define PCIE_HDP_INT_EP_TXEMPTY                (BIT(15))
-#define PCIE_HDP_INT_IPC               (BIT(29))
-
-/* PCIe interrupt status definition */
-#define PCIE_INT_MSI                   (BIT(24))
-#define PCIE_INT_INTX                  (BIT(23))
-
-/* PCIe legacy INTx */
-#define PEARL_PCIE_CFG0_OFFSET         (0x6C)
-#define PEARL_ASSERT_INTX              (BIT(9))
-
-/* SYS CTL regs */
-#define QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET      (0x001C)
-
-#define QTN_PEARL_IPC_IRQ_WORD(irq)    (BIT(irq) | BIT(irq + 16))
-#define QTN_PEARL_LHOST_IPC_IRQ                (6)
-#define QTN_PEARL_LHOST_EP_RESET       (7)
-
-#endif /* __PEARL_PCIE_H */