]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/cadence/macb.c
Merge remote-tracking branches 'asoc/topic/omap' and 'asoc/topic/rcar' into asoc...
[karo-tx-linux.git] / drivers / net / ethernet / cadence / macb.c
index ca97005e24b41217849beaf4b9a578fbaf1f2027..e9daa072ebb4f2c03af453255a9c374bde6ff47c 100644 (file)
@@ -599,25 +599,16 @@ static void gem_rx_refill(struct macb *bp)
 {
        unsigned int            entry;
        struct sk_buff          *skb;
-       struct macb_dma_desc    *desc;
        dma_addr_t              paddr;
 
        while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) {
-               u32 addr, ctrl;
-
                entry = macb_rx_ring_wrap(bp->rx_prepared_head);
-               desc = &bp->rx_ring[entry];
 
                /* Make hw descriptor updates visible to CPU */
                rmb();
 
-               addr = desc->addr;
-               ctrl = desc->ctrl;
                bp->rx_prepared_head++;
 
-               if ((addr & MACB_BIT(RX_USED)))
-                       continue;
-
                if (bp->rx_skbuff[entry] == NULL) {
                        /* allocate sk_buff for this free entry in ring */
                        skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
@@ -698,7 +689,6 @@ static int gem_rx(struct macb *bp, int budget)
                if (!(addr & MACB_BIT(RX_USED)))
                        break;
 
-               desc->addr &= ~MACB_BIT(RX_USED);
                bp->rx_tail++;
                count++;
 
@@ -891,16 +881,15 @@ static int macb_poll(struct napi_struct *napi, int budget)
        if (work_done < budget) {
                napi_complete(napi);
 
-               /*
-                * We've done what we can to clean the buffers. Make sure we
-                * get notified when new packets arrive.
-                */
-               macb_writel(bp, IER, MACB_RX_INT_FLAGS);
-
                /* Packets received while interrupts were disabled */
                status = macb_readl(bp, RSR);
-               if (unlikely(status))
+               if (status) {
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(RCOMP));
                        napi_reschedule(napi);
+               } else {
+                       macb_writel(bp, IER, MACB_RX_INT_FLAGS);
+               }
        }
 
        /* TODO: Handle errors */
@@ -951,6 +940,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                if (unlikely(status & (MACB_TX_ERR_FLAGS))) {
                        macb_writel(bp, IDR, MACB_TX_INT_FLAGS);
                        schedule_work(&bp->tx_error_task);
+
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_TX_ERR_FLAGS);
+
                        break;
                }
 
@@ -968,6 +961,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                                bp->hw_stats.gem.rx_overruns++;
                        else
                                bp->hw_stats.macb.rx_overruns++;
+
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(ISR_ROVR));
                }
 
                if (status & MACB_BIT(HRESP)) {
@@ -977,6 +973,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                         * (work queue?)
                         */
                        netdev_err(dev, "DMA bus error: HRESP not OK\n");
+
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(HRESP));
                }
 
                status = macb_readl(bp, ISR);
@@ -1113,7 +1112,7 @@ 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));
-               dma_unmap_single(&bp->pdev->dev, addr, skb->len,
+               dma_unmap_single(&bp->pdev->dev, addr, bp->rx_buffer_size,
                                 DMA_FROM_DEVICE);
                dev_kfree_skb_any(skb);
                skb = NULL;