net: davinci_emac:Fix translation logic for buffer descriptor
authorSriram <srk@ti.com>
Tue, 22 Mar 2011 02:31:03 +0000 (02:31 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Mar 2011 02:25:05 +0000 (19:25 -0700)
With recent changes to the driver(switch to new cpdma layer),
the support for buffer descriptor address translation logic
is broken. This affects platforms where the physical address of
the descriptors as seen by the DMA engine is different from the
physical address.

Original Patch adding translation logic support:
Commit: ad021ae8862209864dc8ebd3b7d3a55ce84b9ea2

Signed-off-by: Sriramakrishnan A G <srk@ti.com>
Tested-By: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/davinci_cpdma.c
drivers/net/davinci_cpdma.h
drivers/net/davinci_emac.c
include/linux/davinci_emac.h

index e92b2b6cd8c4841733f829c9afa3f48b7e60f0de..ae47f23ba93086855c5709985c368900d2b75b99 100644 (file)
@@ -76,6 +76,7 @@ struct cpdma_desc {
 
 struct cpdma_desc_pool {
        u32                     phys;
+       u32                     hw_addr;
        void __iomem            *iomap;         /* ioremap map */
        void                    *cpumap;        /* dma_alloc map */
        int                     desc_size, mem_size;
@@ -137,7 +138,8 @@ struct cpdma_chan {
  * abstract out these details
  */
 static struct cpdma_desc_pool *
-cpdma_desc_pool_create(struct device *dev, u32 phys, int size, int align)
+cpdma_desc_pool_create(struct device *dev, u32 phys, u32 hw_addr,
+                               int size, int align)
 {
        int bitmap_size;
        struct cpdma_desc_pool *pool;
@@ -161,10 +163,12 @@ cpdma_desc_pool_create(struct device *dev, u32 phys, int size, int align)
        if (phys) {
                pool->phys  = phys;
                pool->iomap = ioremap(phys, size);
+               pool->hw_addr = hw_addr;
        } else {
                pool->cpumap = dma_alloc_coherent(dev, size, &pool->phys,
                                                  GFP_KERNEL);
                pool->iomap = (void __force __iomem *)pool->cpumap;
+               pool->hw_addr = pool->phys;
        }
 
        if (pool->iomap)
@@ -201,14 +205,14 @@ static inline dma_addr_t desc_phys(struct cpdma_desc_pool *pool,
 {
        if (!desc)
                return 0;
-       return pool->phys + (__force dma_addr_t)desc -
+       return pool->hw_addr + (__force dma_addr_t)desc -
                            (__force dma_addr_t)pool->iomap;
 }
 
 static inline struct cpdma_desc __iomem *
 desc_from_phys(struct cpdma_desc_pool *pool, dma_addr_t dma)
 {
-       return dma ? pool->iomap + dma - pool->phys : NULL;
+       return dma ? pool->iomap + dma - pool->hw_addr : NULL;
 }
 
 static struct cpdma_desc __iomem *
@@ -260,6 +264,7 @@ struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params)
 
        ctlr->pool = cpdma_desc_pool_create(ctlr->dev,
                                            ctlr->params.desc_mem_phys,
+                                           ctlr->params.desc_hw_addr,
                                            ctlr->params.desc_mem_size,
                                            ctlr->params.desc_align);
        if (!ctlr->pool) {
index 868e50ebde45c6d9cfa6147c27b3bde5528b9f6b..afa19a0c0d81000d265a8930c9ecec7220863518 100644 (file)
@@ -33,6 +33,7 @@ struct cpdma_params {
        bool                    has_soft_reset;
        int                     min_packet_size;
        u32                     desc_mem_phys;
+       u32                     desc_hw_addr;
        int                     desc_mem_size;
        int                     desc_align;
 
index 082d6ea699206b2a2e0ff2ad7b5cfdd125620e31..baca6bfcb089e7b403134f1bc4fdade1b7b03a69 100644 (file)
@@ -1854,10 +1854,13 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
        dma_params.rxcp                 = priv->emac_base + 0x660;
        dma_params.num_chan             = EMAC_MAX_TXRX_CHANNELS;
        dma_params.min_packet_size      = EMAC_DEF_MIN_ETHPKTSIZE;
-       dma_params.desc_mem_phys        = hw_ram_addr;
+       dma_params.desc_hw_addr         = hw_ram_addr;
        dma_params.desc_mem_size        = pdata->ctrl_ram_size;
        dma_params.desc_align           = 16;
 
+       dma_params.desc_mem_phys = pdata->no_bd_ram ? 0 :
+                       (u32 __force)res->start + pdata->ctrl_ram_offset;
+
        priv->dma = cpdma_ctlr_create(&dma_params);
        if (!priv->dma) {
                dev_err(emac_dev, "DaVinci EMAC: Error initializing DMA\n");
index 5dd428532f794c387533633cba57e6e12957cb01..5428885049941c86e46184deac5bbafa6e9df13a 100644 (file)
@@ -36,6 +36,7 @@ struct emac_platform_data {
 
        u8 rmii_en;
        u8 version;
+       bool no_bd_ram;
        void (*interrupt_enable) (void);
        void (*interrupt_disable) (void);
 };