]> git.hungrycats.org Git - linux/commitdiff
ath10k: fix reading sram contents for QCA4019
authorAshok Raj Nagarajan <arnagara@qti.qualcomm.com>
Sat, 7 Oct 2017 22:36:52 +0000 (22:36 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Nov 2017 09:08:35 +0000 (10:08 +0100)
[ Upstream commit 7f622593cc5add77a99cd39404e8a851be9de792 ]

With QCA4019 platform, SRAM address can be accessed directly from host but
currently, we are assuming sram addresses cannot be accessed directly and
hence we convert the addresses.

While there, clean up growing hw checks during conversion of target CPU
address to CE address. Now we have function pointer pertaining to different
chips.

Signed-off-by: Ashok Raj Nagarajan <arnagara@qti.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/ath/ath10k/ahb.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.h

index 766c63bf05c4a969b774269d2ba4fbe80f629418..45226dbee5ce23c773db06c0d08ece006bcba2c0 100644 (file)
@@ -33,6 +33,9 @@ static const struct of_device_id ath10k_ahb_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, ath10k_ahb_of_match);
 
+#define QCA4019_SRAM_ADDR      0x000C0000
+#define QCA4019_SRAM_LEN       0x00040000 /* 256 kb */
+
 static inline struct ath10k_ahb *ath10k_ahb_priv(struct ath10k *ar)
 {
        return &((struct ath10k_pci *)ar->drv_priv)->ahb[0];
@@ -699,6 +702,25 @@ out:
        return ret;
 }
 
+static u32 ath10k_ahb_qca4019_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+{
+       u32 val = 0, region = addr & 0xfffff;
+
+       val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
+
+       if (region >= QCA4019_SRAM_ADDR && region <=
+           (QCA4019_SRAM_ADDR + QCA4019_SRAM_LEN)) {
+               /* SRAM contents for QCA4019 can be directly accessed and
+                * no conversions are required
+                */
+               val |= region;
+       } else {
+               val |= 0x100000 | region;
+       }
+
+       return val;
+}
+
 static const struct ath10k_hif_ops ath10k_ahb_hif_ops = {
        .tx_sg                  = ath10k_pci_hif_tx_sg,
        .diag_read              = ath10k_pci_hif_diag_read,
@@ -766,6 +788,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev)
        ar_pci->mem_len = ar_ahb->mem_len;
        ar_pci->ar = ar;
        ar_pci->bus_ops = &ath10k_ahb_bus_ops;
+       ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr;
 
        ret = ath10k_pci_setup_resource(ar);
        if (ret) {
index 410bcdaa9e8785d9411de04c90635bdfbbd6d7ae..25b8d501d437e7f9efc4a0caaf8c88af614047e1 100644 (file)
@@ -840,31 +840,35 @@ void ath10k_pci_rx_replenish_retry(unsigned long ptr)
        ath10k_pci_rx_post(ar);
 }
 
-static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+static u32 ath10k_pci_qca988x_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
 {
-       u32 val = 0;
+       u32 val = 0, region = addr & 0xfffff;
 
-       switch (ar->hw_rev) {
-       case ATH10K_HW_QCA988X:
-       case ATH10K_HW_QCA9887:
-       case ATH10K_HW_QCA6174:
-       case ATH10K_HW_QCA9377:
-               val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
-                                         CORE_CTRL_ADDRESS) &
-                      0x7ff) << 21;
-               break;
-       case ATH10K_HW_QCA9888:
-       case ATH10K_HW_QCA99X0:
-       case ATH10K_HW_QCA9984:
-       case ATH10K_HW_QCA4019:
-               val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
-               break;
-       }
+       val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS)
+                                & 0x7ff) << 21;
+       val |= 0x100000 | region;
+       return val;
+}
+
+static u32 ath10k_pci_qca99x0_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+{
+       u32 val = 0, region = addr & 0xfffff;
 
-       val |= 0x100000 | (addr & 0xfffff);
+       val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
+       val |= 0x100000 | region;
        return val;
 }
 
+static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+{
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+       if (WARN_ON_ONCE(!ar_pci->targ_cpu_to_ce_addr))
+               return -ENOTSUPP;
+
+       return ar_pci->targ_cpu_to_ce_addr(ar, addr);
+}
+
 /*
  * Diagnostic read/write access is provided for startup/config/debug usage.
  * Caller must guarantee proper alignment, when applicable, and single user
@@ -3171,6 +3175,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
        bool pci_ps;
        int (*pci_soft_reset)(struct ath10k *ar);
        int (*pci_hard_reset)(struct ath10k *ar);
+       u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
 
        switch (pci_dev->device) {
        case QCA988X_2_0_DEVICE_ID:
@@ -3178,12 +3183,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
                pci_ps = false;
                pci_soft_reset = ath10k_pci_warm_reset;
                pci_hard_reset = ath10k_pci_qca988x_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
                break;
        case QCA9887_1_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA9887;
                pci_ps = false;
                pci_soft_reset = ath10k_pci_warm_reset;
                pci_hard_reset = ath10k_pci_qca988x_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
                break;
        case QCA6164_2_1_DEVICE_ID:
        case QCA6174_2_1_DEVICE_ID:
@@ -3191,30 +3198,35 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
                pci_ps = true;
                pci_soft_reset = ath10k_pci_warm_reset;
                pci_hard_reset = ath10k_pci_qca6174_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
                break;
        case QCA99X0_2_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA99X0;
                pci_ps = false;
                pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
                pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca99x0_targ_cpu_to_ce_addr;
                break;
        case QCA9984_1_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA9984;
                pci_ps = false;
                pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
                pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca99x0_targ_cpu_to_ce_addr;
                break;
        case QCA9888_2_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA9888;
                pci_ps = false;
                pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
                pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca99x0_targ_cpu_to_ce_addr;
                break;
        case QCA9377_1_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA9377;
                pci_ps = true;
                pci_soft_reset = NULL;
                pci_hard_reset = ath10k_pci_qca6174_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
                break;
        default:
                WARN_ON(1);
@@ -3241,6 +3253,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
        ar_pci->bus_ops = &ath10k_pci_bus_ops;
        ar_pci->pci_soft_reset = pci_soft_reset;
        ar_pci->pci_hard_reset = pci_hard_reset;
+       ar_pci->targ_cpu_to_ce_addr = targ_cpu_to_ce_addr;
 
        ar->id.vendor = pdev->vendor;
        ar->id.device = pdev->device;
index 9854ad56b2dea362834c093f2ee13a28f33e2170..577bb87ab2f61eb27f2b6b68a719cfa94ff0c933 100644 (file)
@@ -238,6 +238,11 @@ struct ath10k_pci {
        /* Chip specific pci full reset function */
        int (*pci_hard_reset)(struct ath10k *ar);
 
+       /* chip specific methods for converting target CPU virtual address
+        * space to CE address space
+        */
+       u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
+
        /* Keep this entry in the last, memory for struct ath10k_ahb is
         * allocated (ahb support enabled case) in the continuation of
         * this struct.