wil6210: support 40bit DMA addresses
authorLazar Alexei <qca_ailizaro@qca.qualcomm.com>
Thu, 14 Dec 2017 16:53:06 +0000 (18:53 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 9 Jan 2018 08:03:08 +0000 (10:03 +0200)
Add the option to support 40bit addresses since some platforms
may not support 48bits but support 40bits

Signed-off-by: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/wil6210/pcie_bus.c
drivers/net/wireless/ath/wil6210/pmc.c
drivers/net/wireless/ath/wil6210/txrx.c
drivers/net/wireless/ath/wil6210/wil6210.h

index 9e622ddcc0bb7e2067ea6b03c19b9007fdac2a09..030878b896644d7b474fccbfae610d8126830423 100644 (file)
@@ -204,6 +204,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                .fw_recovery = wil_platform_rop_fw_recovery,
        };
        u32 bar_size = pci_resource_len(pdev, 0);
+       int dma_addr_size[] = {48, 40, 32}; /* keep descending order */
+       int i;
 
        /* check HW */
        dev_info(&pdev->dev, WIL_NAME
@@ -239,21 +241,23 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        /* rollback to err_plat */
 
-       /* device supports 48bit addresses */
-       rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
-       if (rc) {
-               dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc);
-               rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+       /* device supports >32bit addresses */
+       for (i = 0; i < ARRAY_SIZE(dma_addr_size); i++) {
+               rc = dma_set_mask_and_coherent(dev,
+                                              DMA_BIT_MASK(dma_addr_size[i]));
                if (rc) {
-                       dev_err(dev,
-                               "dma_set_mask_and_coherent(32) failed: %d\n",
-                               rc);
-                       goto err_plat;
+                       dev_err(dev, "dma_set_mask_and_coherent(%d) failed: %d\n",
+                               dma_addr_size[i], rc);
+                       continue;
                }
-       } else {
-               wil->use_extended_dma_addr = 1;
+               dev_info(dev, "using dma mask %d", dma_addr_size[i]);
+               wil->dma_addr_size = dma_addr_size[i];
+               break;
        }
 
+       if (wil->dma_addr_size == 0)
+               goto err_plat;
+
        rc = pci_enable_device(pdev);
        if (rc && pdev->msi_enabled == 0) {
                wil_err(wil,
index 2e301b6b32a9ce2a81a97e77affb2f8590cfe390..4ea27b0bd278c94baa490c8ccc73bc8aa1a025d5 100644 (file)
@@ -111,14 +111,14 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
         *
         * HW has limitation that all vrings addresses must share the same
         * upper 16 msb bits part of 48 bits address. To workaround that,
-        * if we are using 48 bit addresses switch to 32 bit allocation
-        * before allocating vring memory.
+        * if we are using more than 32 bit addresses switch to 32 bit
+        * allocation before allocating vring memory.
         *
         * There's no check for the return value of dma_set_mask_and_coherent,
         * since we assume if we were able to set the mask during
         * initialization in this system it will not fail if we set it again
         */
-       if (wil->use_extended_dma_addr)
+       if (wil->dma_addr_size > 32)
                dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 
        pmc->pring_va = dma_alloc_coherent(dev,
@@ -126,8 +126,9 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
                        &pmc->pring_pa,
                        GFP_KERNEL);
 
-       if (wil->use_extended_dma_addr)
-               dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+       if (wil->dma_addr_size > 32)
+               dma_set_mask_and_coherent(dev,
+                                         DMA_BIT_MASK(wil->dma_addr_size));
 
        wil_dbg_misc(wil,
                     "pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
index 389c718cd257f4c1f50e865ccf684f1c051eeef8..62c04f078ebf17a458824568bfe81055dbbc0485 100644 (file)
@@ -178,14 +178,14 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
         *
         * HW has limitation that all vrings addresses must share the same
         * upper 16 msb bits part of 48 bits address. To workaround that,
-        * if we are using 48 bit addresses switch to 32 bit allocation
-        * before allocating vring memory.
+        * if we are using more than 32 bit addresses switch to 32 bit
+        * allocation before allocating vring memory.
         *
         * There's no check for the return value of dma_set_mask_and_coherent,
         * since we assume if we were able to set the mask during
         * initialization in this system it will not fail if we set it again
         */
-       if (wil->use_extended_dma_addr)
+       if (wil->dma_addr_size > 32)
                dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 
        vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
@@ -195,8 +195,9 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
                return -ENOMEM;
        }
 
-       if (wil->use_extended_dma_addr)
-               dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+       if (wil->dma_addr_size > 32)
+               dma_set_mask_and_coherent(dev,
+                                         DMA_BIT_MASK(wil->dma_addr_size));
 
        /* initially, all descriptors are SW owned
         * For Tx and Rx, ownership bit is at the same location, thus
index da0271affa9f08787926ed8e485a2d3c2afaeae7..decbc984694c6d59051e4e9aba84f842b4766230 100644 (file)
@@ -704,7 +704,7 @@ struct wil6210_priv {
        struct wil_sta_info sta[WIL6210_MAX_CID];
        int bcast_vring;
        u32 vring_idle_trsh; /* HW fetches up to 16 descriptors at once  */
-       bool use_extended_dma_addr; /* indicates whether we are using 48 bits */
+       u32 dma_addr_size; /* indicates dma addr size */
        /* scan */
        struct cfg80211_scan_request *scan_request;