net: r6040: Utilize __napi_schedule_irqoff
[cascardo/linux.git] / drivers / net / ethernet / rdc / r6040.c
index 12fc7cd..13ff800 100644 (file)
@@ -614,10 +614,15 @@ static void r6040_tx(struct net_device *dev)
                if (descptr->status & DSC_OWNER_MAC)
                        break; /* Not complete */
                skb_ptr = descptr->skb_ptr;
+
+               /* Statistic Counter */
+               dev->stats.tx_packets++;
+               dev->stats.tx_bytes += skb_ptr->len;
+
                pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
                        skb_ptr->len, PCI_DMA_TODEVICE);
                /* Free buffer */
-               dev_kfree_skb_irq(skb_ptr);
+               dev_kfree_skb(skb_ptr);
                descptr->skb_ptr = NULL;
                /* To next descriptor */
                descptr = descptr->vndescp;
@@ -638,12 +643,15 @@ static int r6040_poll(struct napi_struct *napi, int budget)
        void __iomem *ioaddr = priv->base;
        int work_done;
 
+       r6040_tx(dev);
+
        work_done = r6040_rx(dev, budget);
 
        if (work_done < budget) {
                napi_complete(napi);
-               /* Enable RX interrupt */
-               iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
+               /* Enable RX/TX interrupt */
+               iowrite16(ioread16(ioaddr + MIER) | RX_INTS | TX_INTS,
+                         ioaddr + MIER);
        }
        return work_done;
 }
@@ -670,7 +678,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
        }
 
        /* RX interrupt request */
-       if (status & RX_INTS) {
+       if (status & (RX_INTS | TX_INTS)) {
                if (status & RX_NO_DESC) {
                        /* RX descriptor unavailable */
                        dev->stats.rx_dropped++;
@@ -681,15 +689,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
 
                if (likely(napi_schedule_prep(&lp->napi))) {
                        /* Mask off RX interrupt */
-                       misr &= ~RX_INTS;
-                       __napi_schedule(&lp->napi);
+                       misr &= ~(RX_INTS | TX_INTS);
+                       __napi_schedule_irqoff(&lp->napi);
                }
        }
 
-       /* TX interrupt request */
-       if (status & TX_INTS)
-               r6040_tx(dev);
-
        /* Restore RDC MAC interrupt */
        iowrite16(misr, ioaddr + MIER);
 
@@ -810,6 +814,9 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
        void __iomem *ioaddr = lp->base;
        unsigned long flags;
 
+       if (skb_put_padto(skb, ETH_ZLEN) < 0)
+               return NETDEV_TX_OK;
+
        /* Critical Section */
        spin_lock_irqsave(&lp->lock, flags);
 
@@ -821,17 +828,10 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-       /* Statistic Counter */
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += skb->len;
        /* Set TX descriptor & Transmit it */
        lp->tx_free_desc--;
        descptr = lp->tx_insert_ptr;
-       if (skb->len < ETH_ZLEN)
-               descptr->len = ETH_ZLEN;
-       else
-               descptr->len = skb->len;
-
+       descptr->len = skb->len;
        descptr->skb_ptr = skb;
        descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
                skb->data, skb->len, PCI_DMA_TODEVICE));
@@ -840,7 +840,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
        skb_tx_timestamp(skb);
 
        /* Trigger the MAC to check the TX descriptor */
-       iowrite16(TM2TX, ioaddr + MTPR);
+       if (!skb->xmit_more || netif_queue_stopped(dev))
+               iowrite16(TM2TX, ioaddr + MTPR);
        lp->tx_insert_ptr = descptr->vndescp;
 
        /* If no tx resource, stop */