aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-07-05 03:10:30 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-05 03:10:30 -0400
commit9046a745e29aa4c7e4f1dda3a50199dbe62fc9e8 (patch)
treef118259d55ff9512109eeb38f29e8f77134e11b0 /drivers
parent6ebd1a6d74d5fb684ce9a48ee978e94588ecf502 (diff)
parent9da280413a2a7e03b38c880cf3e7e0c16dd7371b (diff)
Merge branch 'r6040-next'
Florian Fainelli says: ==================== net: r6040: Misc updates Here are some various updates for the r6040 driver, mostly to make it more modern and catch up with the latest API improvements. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/rdc/r6040.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index 7a7a395d0512..cb29ee24cf1b 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2004 Sten Wang <sten.wang@rdc.com.tw> 4 * Copyright (C) 2004 Sten Wang <sten.wang@rdc.com.tw>
5 * Copyright (C) 2007 5 * Copyright (C) 2007
6 * Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us> 6 * Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
7 * Copyright (C) 2007-2012 Florian Fainelli <florian@openwrt.org> 7 * Copyright (C) 2007-2012 Florian Fainelli <f.fainelli@gmail.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -48,8 +48,8 @@
48#include <asm/processor.h> 48#include <asm/processor.h>
49 49
50#define DRV_NAME "r6040" 50#define DRV_NAME "r6040"
51#define DRV_VERSION "0.28" 51#define DRV_VERSION "0.29"
52#define DRV_RELDATE "07Oct2011" 52#define DRV_RELDATE "04Jul2016"
53 53
54/* Time in jiffies before concluding the transmitter is hung. */ 54/* Time in jiffies before concluding the transmitter is hung. */
55#define TX_TIMEOUT (6000 * HZ / 1000) 55#define TX_TIMEOUT (6000 * HZ / 1000)
@@ -162,7 +162,7 @@
162 162
163MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>," 163MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
164 "Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>," 164 "Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>,"
165 "Florian Fainelli <florian@openwrt.org>"); 165 "Florian Fainelli <f.fainelli@gmail.com>");
166MODULE_LICENSE("GPL"); 166MODULE_LICENSE("GPL");
167MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver"); 167MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
168MODULE_VERSION(DRV_VERSION " " DRV_RELDATE); 168MODULE_VERSION(DRV_VERSION " " DRV_RELDATE);
@@ -614,10 +614,15 @@ static void r6040_tx(struct net_device *dev)
614 if (descptr->status & DSC_OWNER_MAC) 614 if (descptr->status & DSC_OWNER_MAC)
615 break; /* Not complete */ 615 break; /* Not complete */
616 skb_ptr = descptr->skb_ptr; 616 skb_ptr = descptr->skb_ptr;
617
618 /* Statistic Counter */
619 dev->stats.tx_packets++;
620 dev->stats.tx_bytes += skb_ptr->len;
621
617 pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), 622 pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
618 skb_ptr->len, PCI_DMA_TODEVICE); 623 skb_ptr->len, PCI_DMA_TODEVICE);
619 /* Free buffer */ 624 /* Free buffer */
620 dev_kfree_skb_irq(skb_ptr); 625 dev_kfree_skb(skb_ptr);
621 descptr->skb_ptr = NULL; 626 descptr->skb_ptr = NULL;
622 /* To next descriptor */ 627 /* To next descriptor */
623 descptr = descptr->vndescp; 628 descptr = descptr->vndescp;
@@ -638,12 +643,15 @@ static int r6040_poll(struct napi_struct *napi, int budget)
638 void __iomem *ioaddr = priv->base; 643 void __iomem *ioaddr = priv->base;
639 int work_done; 644 int work_done;
640 645
646 r6040_tx(dev);
647
641 work_done = r6040_rx(dev, budget); 648 work_done = r6040_rx(dev, budget);
642 649
643 if (work_done < budget) { 650 if (work_done < budget) {
644 napi_complete(napi); 651 napi_complete_done(napi, work_done);
645 /* Enable RX interrupt */ 652 /* Enable RX/TX interrupt */
646 iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER); 653 iowrite16(ioread16(ioaddr + MIER) | RX_INTS | TX_INTS,
654 ioaddr + MIER);
647 } 655 }
648 return work_done; 656 return work_done;
649} 657}
@@ -670,7 +678,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
670 } 678 }
671 679
672 /* RX interrupt request */ 680 /* RX interrupt request */
673 if (status & RX_INTS) { 681 if (status & (RX_INTS | TX_INTS)) {
674 if (status & RX_NO_DESC) { 682 if (status & RX_NO_DESC) {
675 /* RX descriptor unavailable */ 683 /* RX descriptor unavailable */
676 dev->stats.rx_dropped++; 684 dev->stats.rx_dropped++;
@@ -681,15 +689,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
681 689
682 if (likely(napi_schedule_prep(&lp->napi))) { 690 if (likely(napi_schedule_prep(&lp->napi))) {
683 /* Mask off RX interrupt */ 691 /* Mask off RX interrupt */
684 misr &= ~RX_INTS; 692 misr &= ~(RX_INTS | TX_INTS);
685 __napi_schedule(&lp->napi); 693 __napi_schedule_irqoff(&lp->napi);
686 } 694 }
687 } 695 }
688 696
689 /* TX interrupt request */
690 if (status & TX_INTS)
691 r6040_tx(dev);
692
693 /* Restore RDC MAC interrupt */ 697 /* Restore RDC MAC interrupt */
694 iowrite16(misr, ioaddr + MIER); 698 iowrite16(misr, ioaddr + MIER);
695 699
@@ -810,6 +814,9 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
810 void __iomem *ioaddr = lp->base; 814 void __iomem *ioaddr = lp->base;
811 unsigned long flags; 815 unsigned long flags;
812 816
817 if (skb_put_padto(skb, ETH_ZLEN) < 0)
818 return NETDEV_TX_OK;
819
813 /* Critical Section */ 820 /* Critical Section */
814 spin_lock_irqsave(&lp->lock, flags); 821 spin_lock_irqsave(&lp->lock, flags);
815 822
@@ -821,17 +828,10 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
821 return NETDEV_TX_BUSY; 828 return NETDEV_TX_BUSY;
822 } 829 }
823 830
824 /* Statistic Counter */
825 dev->stats.tx_packets++;
826 dev->stats.tx_bytes += skb->len;
827 /* Set TX descriptor & Transmit it */ 831 /* Set TX descriptor & Transmit it */
828 lp->tx_free_desc--; 832 lp->tx_free_desc--;
829 descptr = lp->tx_insert_ptr; 833 descptr = lp->tx_insert_ptr;
830 if (skb->len < ETH_ZLEN) 834 descptr->len = skb->len;
831 descptr->len = ETH_ZLEN;
832 else
833 descptr->len = skb->len;
834
835 descptr->skb_ptr = skb; 835 descptr->skb_ptr = skb;
836 descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, 836 descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
837 skb->data, skb->len, PCI_DMA_TODEVICE)); 837 skb->data, skb->len, PCI_DMA_TODEVICE));
@@ -840,7 +840,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
840 skb_tx_timestamp(skb); 840 skb_tx_timestamp(skb);
841 841
842 /* Trigger the MAC to check the TX descriptor */ 842 /* Trigger the MAC to check the TX descriptor */
843 iowrite16(TM2TX, ioaddr + MTPR); 843 if (!skb->xmit_more || netif_queue_stopped(dev))
844 iowrite16(TM2TX, ioaddr + MTPR);
844 lp->tx_insert_ptr = descptr->vndescp; 845 lp->tx_insert_ptr = descptr->vndescp;
845 846
846 /* If no tx resource, stop */ 847 /* If no tx resource, stop */
@@ -1001,14 +1002,8 @@ static void r6040_adjust_link(struct net_device *dev)
1001 lp->old_duplex = phydev->duplex; 1002 lp->old_duplex = phydev->duplex;
1002 } 1003 }
1003 1004
1004 if (status_changed) { 1005 if (status_changed)
1005 pr_info("%s: link %s", dev->name, phydev->link ? 1006 phy_print_status(phydev);
1006 "UP" : "DOWN");
1007 if (phydev->link)
1008 pr_cont(" - %d/%s", phydev->speed,
1009 DUPLEX_FULL == phydev->duplex ? "full" : "half");
1010 pr_cont("\n");
1011 }
1012} 1007}
1013 1008
1014static int r6040_mii_probe(struct net_device *dev) 1009static int r6040_mii_probe(struct net_device *dev)