wil6210: set dma mask to reflect device capability

11ad device supports 48 bit addresses, reflect that
by setting the dma mask accordingly to be able to
map skbs using 48 bits.

HW has limitation that all vrings should share the same
msb bits out of the 48 bits address. To overcome that,
for vrings mapping use 32 bit addresses only.

Change-Id: I7f710129ba61356f7f29ec69c885f60a31246151
CRs-Fixed: 1109659
Signed-off-by: Hamad Kadmany <hkadmany@codeaurora.org>
This commit is contained in:
Hamad Kadmany 2017-01-17 16:48:25 +02:00
parent a6d83d2e8e
commit 2c79dad3a7
4 changed files with 51 additions and 2 deletions

View file

@ -187,6 +187,22 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev_err(dev, "wil_if_alloc failed: %d\n", rc); dev_err(dev, "wil_if_alloc failed: %d\n", rc);
return rc; return rc;
} }
/* device supports 48 bit 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));
if (rc) {
dev_err(dev,
"dma_set_mask_and_coherent(32) failed: %d\n",
rc);
goto if_free;
}
} else {
wil->use_extended_dma_addr = 1;
}
wil->pdev = pdev; wil->pdev = pdev;
pci_set_drvdata(pdev, wil); pci_set_drvdata(pdev, wil);
/* rollback to if_free */ /* rollback to if_free */

View file

@ -108,13 +108,28 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
/* Allocate pring buffer and descriptors. /* Allocate pring buffer and descriptors.
* vring->va should be aligned on its size rounded up to power of 2 * vring->va should be aligned on its size rounded up to power of 2
* This is granted by the dma_alloc_coherent * This is granted by the dma_alloc_coherent.
*
* 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.
*
* 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)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
pmc->pring_va = dma_alloc_coherent(dev, pmc->pring_va = dma_alloc_coherent(dev,
sizeof(struct vring_tx_desc) * num_descriptors, sizeof(struct vring_tx_desc) * num_descriptors,
&pmc->pring_pa, &pmc->pring_pa,
GFP_KERNEL); GFP_KERNEL);
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
wil_dbg_misc(wil, wil_dbg_misc(wil,
"%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n", "%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
__func__, __func__,

View file

@ -123,15 +123,32 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
vring->va = NULL; vring->va = NULL;
return -ENOMEM; return -ENOMEM;
} }
/* vring->va should be aligned on its size rounded up to power of 2 /* vring->va should be aligned on its size rounded up to power of 2
* This is granted by the dma_alloc_coherent * This is granted by the dma_alloc_coherent.
*
* 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.
*
* 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)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
if (!vring->va) { if (!vring->va) {
kfree(vring->ctx); kfree(vring->ctx);
vring->ctx = NULL; vring->ctx = NULL;
return -ENOMEM; return -ENOMEM;
} }
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
/* initially, all descriptors are SW owned /* initially, all descriptors are SW owned
* For Tx and Rx, ownership bit is at the same location, thus * For Tx and Rx, ownership bit is at the same location, thus
* we can use any * we can use any

View file

@ -647,6 +647,7 @@ struct wil6210_priv {
u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
struct wil_sta_info sta[WIL6210_MAX_CID]; struct wil_sta_info sta[WIL6210_MAX_CID];
int bcast_vring; int bcast_vring;
bool use_extended_dma_addr; /* indicates whether we are using 48 bits */
/* scan */ /* scan */
struct cfg80211_scan_request *scan_request; struct cfg80211_scan_request *scan_request;