Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / ethernet / cadence / macb.c
index d954a97..0294b6a 100644 (file)
@@ -541,6 +541,14 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb)
        }
 }
 
+static inline void macb_set_addr(struct macb_dma_desc *desc, dma_addr_t addr)
+{
+       desc->addr = (u32)addr;
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       desc->addrh = (u32)(addr >> 32);
+#endif
+}
+
 static void macb_tx_error_task(struct work_struct *work)
 {
        struct macb_queue       *queue = container_of(work, struct macb_queue,
@@ -621,14 +629,17 @@ static void macb_tx_error_task(struct work_struct *work)
 
        /* Set end of TX queue */
        desc = macb_tx_desc(queue, 0);
-       desc->addr = 0;
+       macb_set_addr(desc, 0);
        desc->ctrl = MACB_BIT(TX_USED);
 
        /* Make descriptor updates visible to hardware */
        wmb();
 
        /* Reinitialize the TX desc queue */
-       queue_writel(queue, TBQP, queue->tx_ring_dma);
+       queue_writel(queue, TBQP, (u32)(queue->tx_ring_dma));
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       queue_writel(queue, TBQPH, (u32)(queue->tx_ring_dma >> 32));
+#endif
        /* Make TX ring reflect state of hardware */
        queue->tx_head = 0;
        queue->tx_tail = 0;
@@ -750,7 +761,7 @@ static void gem_rx_refill(struct macb *bp)
 
                        if (entry == RX_RING_SIZE - 1)
                                paddr |= MACB_BIT(RX_WRAP);
-                       bp->rx_ring[entry].addr = paddr;
+                       macb_set_addr(&(bp->rx_ring[entry]), paddr);
                        bp->rx_ring[entry].ctrl = 0;
 
                        /* properly align Ethernet header */
@@ -798,7 +809,9 @@ static int gem_rx(struct macb *bp, int budget)
        int                     count = 0;
 
        while (count < budget) {
-               u32 addr, ctrl;
+               u32 ctrl;
+               dma_addr_t addr;
+               bool rxused;
 
                entry = macb_rx_ring_wrap(bp->rx_tail);
                desc = &bp->rx_ring[entry];
@@ -806,10 +819,14 @@ static int gem_rx(struct macb *bp, int budget)
                /* Make hw descriptor updates visible to CPU */
                rmb();
 
-               addr = desc->addr;
+               rxused = (desc->addr & MACB_BIT(RX_USED)) ? true : false;
+               addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               addr |= ((u64)(desc->addrh) << 32);
+#endif
                ctrl = desc->ctrl;
 
-               if (!(addr & MACB_BIT(RX_USED)))
+               if (!rxused)
                        break;
 
                bp->rx_tail++;
@@ -835,7 +852,6 @@ static int gem_rx(struct macb *bp, int budget)
                netdev_vdbg(bp->dev, "gem_rx %u (len %u)\n", entry, len);
 
                skb_put(skb, len);
-               addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr));
                dma_unmap_single(&bp->pdev->dev, addr,
                                 bp->rx_buffer_size, DMA_FROM_DEVICE);
 
@@ -1299,7 +1315,7 @@ static unsigned int macb_tx_map(struct macb *bp,
                        ctrl |= MACB_BIT(TX_WRAP);
 
                /* Set TX buffer descriptor */
-               desc->addr = tx_skb->mapping;
+               macb_set_addr(desc, tx_skb->mapping);
                /* desc->addr must be visible to hardware before clearing
                 * 'TX_USED' bit in desc->ctrl.
                 */
@@ -1445,6 +1461,9 @@ static void gem_free_rx_buffers(struct macb *bp)
 
                desc = &bp->rx_ring[i];
                addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               addr |= ((u64)(desc->addrh) << 32);
+#endif
                dma_unmap_single(&bp->pdev->dev, addr, bp->rx_buffer_size,
                                 DMA_FROM_DEVICE);
                dev_kfree_skb_any(skb);
@@ -1570,7 +1589,7 @@ static void gem_init_rings(struct macb *bp)
 
        for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
                for (i = 0; i < TX_RING_SIZE; i++) {
-                       queue->tx_ring[i].addr = 0;
+                       macb_set_addr(&(queue->tx_ring[i]), 0);
                        queue->tx_ring[i].ctrl = MACB_BIT(TX_USED);
                }
                queue->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
@@ -1717,6 +1736,10 @@ static void macb_configure_dma(struct macb *bp)
                        dmacfg |= GEM_BIT(TXCOEN);
                else
                        dmacfg &= ~GEM_BIT(TXCOEN);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               dmacfg |= GEM_BIT(ADDR64);
+#endif
                netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
                           dmacfg);
                gem_writel(bp, DMACFG, dmacfg);
@@ -1762,9 +1785,15 @@ static void macb_init_hw(struct macb *bp)
        macb_configure_dma(bp);
 
        /* Initialize TX and RX buffers */
-       macb_writel(bp, RBQP, bp->rx_ring_dma);
+       macb_writel(bp, RBQP, (u32)(bp->rx_ring_dma));
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       macb_writel(bp, RBQPH, (u32)(bp->rx_ring_dma >> 32));
+#endif
        for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
-               queue_writel(queue, TBQP, queue->tx_ring_dma);
+               queue_writel(queue, TBQP, (u32)(queue->tx_ring_dma));
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               queue_writel(queue, TBQPH, (u32)(queue->tx_ring_dma >> 32));
+#endif
 
                /* Enable interrupts */
                queue_writel(queue, IER,
@@ -2326,7 +2355,8 @@ static void macb_probe_queues(void __iomem *mem,
 }
 
 static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
-                        struct clk **hclk, struct clk **tx_clk)
+                        struct clk **hclk, struct clk **tx_clk,
+                        struct clk **rx_clk)
 {
        int err;
 
@@ -2348,6 +2378,10 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
        if (IS_ERR(*tx_clk))
                *tx_clk = NULL;
 
+       *rx_clk = devm_clk_get(&pdev->dev, "rx_clk");
+       if (IS_ERR(*rx_clk))
+               *rx_clk = NULL;
+
        err = clk_prepare_enable(*pclk);
        if (err) {
                dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err);
@@ -2366,8 +2400,17 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
                goto err_disable_hclk;
        }
 
+       err = clk_prepare_enable(*rx_clk);
+       if (err) {
+               dev_err(&pdev->dev, "failed to enable rx_clk (%u)\n", err);
+               goto err_disable_txclk;
+       }
+
        return 0;
 
+err_disable_txclk:
+       clk_disable_unprepare(*tx_clk);
+
 err_disable_hclk:
        clk_disable_unprepare(*hclk);
 
@@ -2402,6 +2445,9 @@ static int macb_init(struct platform_device *pdev)
                        queue->IDR  = GEM_IDR(hw_q - 1);
                        queue->IMR  = GEM_IMR(hw_q - 1);
                        queue->TBQP = GEM_TBQP(hw_q - 1);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+                       queue->TBQPH = GEM_TBQPH(hw_q -1);
+#endif
                } else {
                        /* queue0 uses legacy registers */
                        queue->ISR  = MACB_ISR;
@@ -2409,6 +2455,9 @@ static int macb_init(struct platform_device *pdev)
                        queue->IDR  = MACB_IDR;
                        queue->IMR  = MACB_IMR;
                        queue->TBQP = MACB_TBQP;
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+                       queue->TBQPH = MACB_TBQPH;
+#endif
                }
 
                /* get irq: here we use the linux queue index, not the hardware
@@ -2751,12 +2800,14 @@ static const struct net_device_ops at91ether_netdev_ops = {
 };
 
 static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
-                             struct clk **hclk, struct clk **tx_clk)
+                             struct clk **hclk, struct clk **tx_clk,
+                             struct clk **rx_clk)
 {
        int err;
 
        *hclk = NULL;
        *tx_clk = NULL;
+       *rx_clk = NULL;
 
        *pclk = devm_clk_get(&pdev->dev, "ether_clk");
        if (IS_ERR(*pclk))
@@ -2880,13 +2931,13 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids);
 static int macb_probe(struct platform_device *pdev)
 {
        int (*clk_init)(struct platform_device *, struct clk **,
-                       struct clk **, struct clk **)
+                       struct clk **, struct clk **,  struct clk **)
                                              = macb_clk_init;
        int (*init)(struct platform_device *) = macb_init;
        struct device_node *np = pdev->dev.of_node;
        struct device_node *phy_node;
        const struct macb_config *macb_config = NULL;
-       struct clk *pclk, *hclk = NULL, *tx_clk = NULL;
+       struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
        unsigned int queue_mask, num_queues;
        struct macb_platform_data *pdata;
        bool native_io;
@@ -2914,7 +2965,7 @@ static int macb_probe(struct platform_device *pdev)
                }
        }
 
-       err = clk_init(pdev, &pclk, &hclk, &tx_clk);
+       err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk);
        if (err)
                return err;
 
@@ -2950,6 +3001,7 @@ static int macb_probe(struct platform_device *pdev)
        bp->pclk = pclk;
        bp->hclk = hclk;
        bp->tx_clk = tx_clk;
+       bp->rx_clk = rx_clk;
        if (macb_config)
                bp->jumbo_max_len = macb_config->jumbo_max_len;
 
@@ -2958,6 +3010,11 @@ static int macb_probe(struct platform_device *pdev)
                bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
        device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);
 
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+       if (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1)) > GEM_DBW32)
+               dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
+#endif
+
        spin_lock_init(&bp->lock);
 
        /* setup capabilities */
@@ -2968,7 +3025,7 @@ static int macb_probe(struct platform_device *pdev)
        dev->irq = platform_get_irq(pdev, 0);
        if (dev->irq < 0) {
                err = dev->irq;
-               goto err_disable_clocks;
+               goto err_out_free_netdev;
        }
 
        mac = of_get_mac_address(np);
@@ -3043,6 +3100,7 @@ err_disable_clocks:
        clk_disable_unprepare(tx_clk);
        clk_disable_unprepare(hclk);
        clk_disable_unprepare(pclk);
+       clk_disable_unprepare(rx_clk);
 
        return err;
 }
@@ -3069,6 +3127,7 @@ static int macb_remove(struct platform_device *pdev)
                clk_disable_unprepare(bp->tx_clk);
                clk_disable_unprepare(bp->hclk);
                clk_disable_unprepare(bp->pclk);
+               clk_disable_unprepare(bp->rx_clk);
                free_netdev(dev);
        }
 
@@ -3092,6 +3151,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
                clk_disable_unprepare(bp->tx_clk);
                clk_disable_unprepare(bp->hclk);
                clk_disable_unprepare(bp->pclk);
+               clk_disable_unprepare(bp->rx_clk);
        }
 
        return 0;
@@ -3111,6 +3171,7 @@ static int __maybe_unused macb_resume(struct device *dev)
                clk_prepare_enable(bp->pclk);
                clk_prepare_enable(bp->hclk);
                clk_prepare_enable(bp->tx_clk);
+               clk_prepare_enable(bp->rx_clk);
        }
 
        netif_device_attach(netdev);