diff options
authorAndre Przywara <andre.przywara@arm.com>2020-03-24 13:23:47 +0000
committerDavid S. Miller <davem@davemloft.net>2020-03-24 16:33:05 -0700
commit5fff0151b3244dc1ef9df7a5d1c0f79eb42599d7 (patch)
parentnet: axienet: Autodetect 64-bit DMA capability (diff)
net: axienet: Allow DMA to beyond 4GB
With all DMA address accesses wrapped, we can actually support 64-bit DMA if this option was chosen at IP integration time. If the IP has been configured for an address width greater than 32 bits, we assume the full 64 bit DMA width is working. In practise this will be limited by the actual system address bus width, which will ideally be the same as the DMA IP address width. If this is not the case, the actual width can still be configured using a dma-ranges property in the parent of the MAC node. This increases the DMA mask on those systems to let the kernel choose buffers from memory at higher addresses. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index a54a5c754da0..fa5dc2993520 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1780,6 +1780,7 @@ static int axienet_probe(struct platform_device *pdev)
struct net_device *ndev;
const void *mac_addr;
struct resource *ethres;
+ int addr_width = 32;
u32 value;
ndev = alloc_etherdev(sizeof(*lp));
@@ -1947,6 +1948,7 @@ static int axienet_probe(struct platform_device *pdev)
iowrite32(0xffffffff, desc);
if (ioread32(desc) > 0) {
lp->features |= XAE_FEATURE_DMA_64BIT;
+ addr_width = 64;
"autodetected 64-bit DMA range\n");
@@ -1954,6 +1956,12 @@ static int axienet_probe(struct platform_device *pdev)
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width));
+ if (ret) {
+ dev_err(&pdev->dev, "No suitable DMA available\n");
+ goto free_netdev;
+ }
/* Check for Ethernet core IRQ (optional) */
if (lp->eth_irq <= 0)
dev_info(&pdev->dev, "Ethernet core IRQ not defined\n");