linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / net / via-rhine.c
index ae97108..56864ff 100644 (file)
        version. He may or may not be interested in bug reports on this
        code. You can find his versions at:
        http://www.scyld.com/network/via-rhine.html
-       [link no longer provides useful info -jgarzik]
+
+
+       Linux kernel version history:
+
+       LK1.1.0:
+       - Jeff Garzik: softnet 'n stuff
+
+       LK1.1.1:
+       - Justin Guyett: softnet and locking fixes
+       - Jeff Garzik: use PCI interface
+
+       LK1.1.2:
+       - Urban Widmark: minor cleanups, merges from Becker 1.03a/1.04 versions
+
+       LK1.1.3:
+       - Urban Widmark: use PCI DMA interface (with thanks to the eepro100.c
+                        code) update "Theory of Operation" with
+                        softnet/locking changes
+       - Dave Miller: PCI DMA and endian fixups
+       - Jeff Garzik: MOD_xxx race fixes, updated PCI resource allocation
+
+       LK1.1.4:
+       - Urban Widmark: fix gcc 2.95.2 problem and
+                        remove writel's to fixed address 0x7c
+
+       LK1.1.5:
+       - Urban Widmark: mdio locking, bounce buffer changes
+                        merges from Beckers 1.05 version
+                        added netif_running_on/off support
+
+       LK1.1.6:
+       - Urban Widmark: merges from Beckers 1.08b version (VT6102 + mdio)
+                        set netif_running_on/off on startup, del_timer_sync
+
+       LK1.1.7:
+       - Manfred Spraul: added reset into tx_timeout
+
+       LK1.1.9:
+       - Urban Widmark: merges from Beckers 1.10 version
+                        (media selection + eeprom reload)
+       - David Vrabel:  merges from D-Link "1.11" version
+                        (disable WOL and PME on startup)
+
+       LK1.1.10:
+       - Manfred Spraul: use "singlecopy" for unaligned buffers
+                         don't allocate bounce buffers for !ReqTxAlign cards
+
+       LK1.1.11:
+       - David Woodhouse: Set dev->base_addr before the first time we call
+                          wait_for_reset(). It's a lot happier that way.
+                          Free np->tx_bufs only if we actually allocated it.
+
+       LK1.1.12:
+       - Martin Eriksson: Allow Memory-Mapped IO to be enabled.
+
+       LK1.1.13 (jgarzik):
+       - Add ethtool support
+       - Replace some MII-related magic numbers with constants
+
+       LK1.1.14 (Ivan G.):
+       - fixes comments for Rhine-III
+       - removes W_MAX_TIMEOUT (unused)
+       - adds HasDavicomPhy for Rhine-I (basis: linuxfet driver; my card
+         is R-I and has Davicom chip, flag is referenced in kernel driver)
+       - sends chip_id as a parameter to wait_for_reset since np is not
+         initialized on first call
+       - changes mmio "else if (chip_id==VT6102)" to "else" so it will work
+         for Rhine-III's (documentation says same bit is correct)
+       - transmit frame queue message is off by one - fixed
+       - adds IntrNormalSummary to "Something Wicked" exclusion list
+         so normal interrupts will not trigger the message (src: Donald Becker)
+       (Roger Luethi)
+       - show confused chip where to continue after Tx error
+       - location of collision counter is chip specific
+       - allow selecting backoff algorithm (module parameter)
+
+       LK1.1.15 (jgarzik):
+       - Use new MII lib helper generic_mii_ioctl
+
+       LK1.1.16 (Roger Luethi)
+       - Etherleak fix
+       - Handle Tx buffer underrun
+       - Fix bugs in full duplex handling
+       - New reset code uses "force reset" cmd on Rhine-II
+       - Various clean ups
+
+       LK1.1.17 (Roger Luethi)
+       - Fix race in via_rhine_start_tx()
+       - On errors, wait for Tx engine to turn off before scavenging
+       - Handle Tx descriptor write-back race on Rhine-II
+       - Force flushing for PCI posted writes
+       - More reset code changes
+
+       LK1.1.18 (Roger Luethi)
+       - No filtering multicast in promisc mode (Edward Peng)
+       - Fix for Rhine-I Tx timeouts
+
+       LK1.1.19 (Roger Luethi)
+       - Increase Tx threshold for unspecified errors
+
+       LK1.2.0-2.6 (Roger Luethi)
+       - Massive clean-up
+       - Rewrite PHY, media handling (remove options, full_duplex, backoff)
+       - Fix Tx engine race for good
+       - Craig Brind: Zero padded aligned buffers for short packets.
 
 */
 
 #define DRV_NAME       "via-rhine"
-#define DRV_VERSION    "1.4.1"
-#define DRV_RELDATE    "July-24-2006"
+#define DRV_VERSION    "1.2.0-2.6"
+#define DRV_RELDATE    "June-10-2004"
 
 
 /* A few user-configurable values.
@@ -44,10 +148,6 @@ static int max_interrupt_work = 20;
    Setting to > 1518 effectively disables this feature. */
 static int rx_copybreak;
 
-/* Work-around for broken BIOSes: they are unable to get the chip back out of
-   power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
-static int avoid_D3;
-
 /*
  * In case you are looking for 'options[]' or 'full_duplex[]', they
  * are gone. Use ethtool(8) instead.
@@ -67,11 +167,7 @@ static const int multicast_filter_limit = 32;
    There are no ill effects from too-large receive rings. */
 #define TX_RING_SIZE   16
 #define TX_QUEUE_LEN   10      /* Limit ring entries actually used. */
-#ifdef CONFIG_VIA_RHINE_NAPI
-#define RX_RING_SIZE   64
-#else
 #define RX_RING_SIZE   16
-#endif
 
 
 /* Operational parameters that usually are not changed. */
@@ -124,11 +220,9 @@ MODULE_LICENSE("GPL");
 module_param(max_interrupt_work, int, 0);
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
-module_param(avoid_D3, bool, 0);
 MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
 
 /*
                Theory of Operation
@@ -262,11 +356,12 @@ enum rhine_quirks {
 /* Beware of PCI posted writes */
 #define IOSYNC do { ioread8(ioaddr + StationAddr); } while (0)
 
-static const struct pci_device_id rhine_pci_tbl[] = {
-       { 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },    /* VT86C100A */
-       { 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },    /* VT6102 */
-       { 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },    /* 6105{,L,LOM} */
-       { 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, },    /* VT6105M */
+static struct pci_device_id rhine_pci_tbl[] =
+{
+       {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT86C100A */
+       {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6102 */
+       {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* 6105{,L,LOM} */
+       {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6105M */
        { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
@@ -375,7 +470,7 @@ struct rhine_private {
        struct sk_buff *tx_skbuff[TX_RING_SIZE];
        dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
 
-       /* Tx bounce buffers (Rhine-I only) */
+       /* Tx bounce buffers */
        unsigned char *tx_buf[TX_RING_SIZE];
        unsigned char *tx_bufs;
        dma_addr_t tx_bufs_dma;
@@ -396,6 +491,8 @@ struct rhine_private {
        u8 tx_thresh, rx_thresh;
 
        struct mii_if_info mii_if;
+       struct work_struct tx_timeout_task;
+       struct work_struct check_media_task;
        void __iomem *base;
 };
 
@@ -403,10 +500,12 @@ static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
+static void rhine_tx_timeout_task(struct net_device *dev);
+static void rhine_check_media_task(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static void rhine_tx(struct net_device *dev);
-static int rhine_rx(struct net_device *dev, int limit);
+static void rhine_rx(struct net_device *dev);
 static void rhine_error(struct net_device *dev, int intr_status);
 static void rhine_set_rx_mode(struct net_device *dev);
 static struct net_device_stats *rhine_get_stats(struct net_device *dev);
@@ -574,32 +673,6 @@ static void rhine_poll(struct net_device *dev)
 }
 #endif
 
-#ifdef CONFIG_VIA_RHINE_NAPI
-static int rhine_napipoll(struct net_device *dev, int *budget)
-{
-       struct rhine_private *rp = netdev_priv(dev);
-       void __iomem *ioaddr = rp->base;
-       int done, limit = min(dev->quota, *budget);
-
-       done = rhine_rx(dev, limit);
-       *budget -= done;
-       dev->quota -= done;
-
-       if (done < limit) {
-               netif_rx_complete(dev);
-
-               iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
-                         IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
-                         IntrTxDone | IntrTxError | IntrTxUnderrun |
-                         IntrPCIErr | IntrStatsMax | IntrLinkChange,
-                         ioaddr + IntrEnable);
-               return 0;
-       }
-       else
-               return 1;
-}
-#endif
-
 static void rhine_hw_init(struct net_device *dev, long pioaddr)
 {
        struct rhine_private *rp = netdev_priv(dev);
@@ -779,14 +852,16 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        dev->watchdog_timeo = TX_TIMEOUT;
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = rhine_poll;
-#endif
-#ifdef CONFIG_VIA_RHINE_NAPI
-       dev->poll = rhine_napipoll;
-       dev->weight = 64;
 #endif
        if (rp->quirks & rqRhineI)
                dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
+       INIT_WORK(&rp->tx_timeout_task,
+                 (void (*)(void *))rhine_tx_timeout_task, dev);
+
+       INIT_WORK(&rp->check_media_task,
+                 (void (*)(void *))rhine_check_media_task, dev);
+
        /* dev->name not defined before register_netdev()! */
        rc = register_netdev(dev);
        if (rc)
@@ -829,9 +904,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
                }
        }
        rp->mii_if.phy_id = phy_id;
-       if (debug > 1 && avoid_D3)
-               printk(KERN_INFO "%s: No D3 power state at shutdown.\n",
-                      dev->name);
 
        return 0;
 
@@ -972,8 +1044,7 @@ static void alloc_tbufs(struct net_device* dev)
                rp->tx_ring[i].desc_length = cpu_to_le32(TXDESC);
                next += sizeof(struct tx_desc);
                rp->tx_ring[i].next_desc = cpu_to_le32(next);
-               if (rp->quirks & rqRhineI)
-                       rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ];
+               rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ];
        }
        rp->tx_ring[i-1].next_desc = cpu_to_le32(rp->tx_ring_dma);
 
@@ -1015,25 +1086,11 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
        else
            iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
                   ioaddr + ChipCmd1);
-       if (debug > 1)
-               printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name,
-                       rp->mii_if.force_media, netif_carrier_ok(dev));
 }
 
-/* Called after status of force_media possibly changed */
-static void rhine_set_carrier(struct mii_if_info *mii)
+static void rhine_check_media_task(struct net_device *dev)
 {
-       if (mii->force_media) {
-               /* autoneg is off: Link is always assumed to be up */
-               if (!netif_carrier_ok(mii->dev))
-                       netif_carrier_on(mii->dev);
-       }
-       else    /* Let MMI library update carrier status */
-               rhine_check_media(mii->dev, 0);
-       if (debug > 1)
-               printk(KERN_INFO "%s: force_media %d, carrier %d\n",
-                      mii->dev->name, mii->force_media,
-                      netif_carrier_ok(mii->dev));
+       rhine_check_media(dev, 0);
 }
 
 static void init_registers(struct net_device *dev)
@@ -1057,8 +1114,6 @@ static void init_registers(struct net_device *dev)
 
        rhine_set_rx_mode(dev);
 
-       netif_poll_enable(dev);
-
        /* Enable interrupts by setting the interrupt mask. */
        iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
               IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
@@ -1091,8 +1146,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
        if (quirks & rqRhineI) {
                iowrite8(0x01, ioaddr + MIIRegAddr);    // MII_BMSR
 
-               /* Can be called from ISR. Evil. */
-               mdelay(1);
+               /* Do not call from ISR! */
+               msleep(1);
 
                /* 0x80 must be set immediately before turning it off */
                iowrite8(0x80, ioaddr + MIICmd);
@@ -1150,7 +1205,7 @@ static int rhine_open(struct net_device *dev)
        void __iomem *ioaddr = rp->base;
        int rc;
 
-       rc = request_irq(rp->pdev->irq, &rhine_interrupt, IRQF_SHARED, dev->name,
+       rc = request_irq(rp->pdev->irq, &rhine_interrupt, SA_SHIRQ, dev->name,
                        dev);
        if (rc)
                return rc;
@@ -1180,6 +1235,16 @@ static int rhine_open(struct net_device *dev)
 }
 
 static void rhine_tx_timeout(struct net_device *dev)
+{
+       struct rhine_private *rp = netdev_priv(dev);
+
+       /*
+        * Move bulk of work outside of interrupt context
+        */
+       schedule_work(&rp->tx_timeout_task);
+}
+
+static void rhine_tx_timeout_task(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
        void __iomem *ioaddr = rp->base;
@@ -1224,8 +1289,11 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
        /* Calculate the next Tx descriptor entry. */
        entry = rp->cur_tx % TX_RING_SIZE;
 
-       if (skb_padto(skb, ETH_ZLEN))
-               return 0;
+       if (skb->len < ETH_ZLEN) {
+               skb = skb_padto(skb, ETH_ZLEN);
+               if (skb == NULL)
+                       return 0;
+       }
 
        rp->tx_skbuff[entry] = skb;
 
@@ -1313,18 +1381,8 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *
                               dev->name, intr_status);
 
                if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
-                                  IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
-#ifdef CONFIG_VIA_RHINE_NAPI
-                       iowrite16(IntrTxAborted |
-                                 IntrTxDone | IntrTxError | IntrTxUnderrun |
-                                 IntrPCIErr | IntrStatsMax | IntrLinkChange,
-                                 ioaddr + IntrEnable);
-
-                       netif_rx_schedule(dev);
-#else
-                       rhine_rx(dev, RX_RING_SIZE);
-#endif
-               }
+                   IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf))
+                       rhine_rx(dev);
 
                if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
                        if (intr_status & IntrTxErrSummary) {
@@ -1422,12 +1480,13 @@ static void rhine_tx(struct net_device *dev)
        spin_unlock(&rp->lock);
 }
 
-/* Process up to limit frames from receive ring */
-static int rhine_rx(struct net_device *dev, int limit)
+/* This routine is logically part of the interrupt handler, but isolated
+   for clarity and better register allocation. */
+static void rhine_rx(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
-       int count;
        int entry = rp->cur_rx % RX_RING_SIZE;
+       int boguscnt = rp->dirty_rx + RX_RING_SIZE - rp->cur_rx;
 
        if (debug > 4) {
                printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n",
@@ -1436,18 +1495,16 @@ static int rhine_rx(struct net_device *dev, int limit)
        }
 
        /* If EOP is set on the next entry, it's a new packet. Send it up. */
-       for (count = 0; count < limit; ++count) {
+       while (!(rp->rx_head_desc->rx_status & cpu_to_le32(DescOwn))) {
                struct rx_desc *desc = rp->rx_head_desc;
                u32 desc_status = le32_to_cpu(desc->rx_status);
                int data_size = desc_status >> 16;
 
-               if (desc_status & DescOwn)
-                       break;
-
                if (debug > 4)
                        printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n",
                               desc_status);
-
+               if (--boguscnt < 0)
+                       break;
                if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) {
                        if ((desc_status & RxWholePkt) != RxWholePkt) {
                                printk(KERN_WARNING "%s: Oversized Ethernet "
@@ -1516,11 +1573,7 @@ static int rhine_rx(struct net_device *dev, int limit)
                                                 PCI_DMA_FROMDEVICE);
                        }
                        skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_VIA_RHINE_NAPI
-                       netif_receive_skb(skb);
-#else
                        netif_rx(skb);
-#endif
                        dev->last_rx = jiffies;
                        rp->stats.rx_bytes += pkt_len;
                        rp->stats.rx_packets++;
@@ -1547,8 +1600,6 @@ static int rhine_rx(struct net_device *dev, int limit)
                }
                rp->rx_ring[entry].rx_status = cpu_to_le32(DescOwn);
        }
-
-       return count;
 }
 
 /*
@@ -1606,7 +1657,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
        spin_lock(&rp->lock);
 
        if (intr_status & IntrLinkChange)
-               rhine_check_media(dev, 0);
+               schedule_work(&rp->check_media_task);
        if (intr_status & IntrStatsMax) {
                rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
                rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1737,7 +1788,6 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        spin_lock_irq(&rp->lock);
        rc = mii_ethtool_sset(&rp->mii_if, cmd);
        spin_unlock_irq(&rp->lock);
-       rhine_set_carrier(&rp->mii_if);
 
        return rc;
 }
@@ -1825,7 +1875,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        spin_lock_irq(&rp->lock);
        rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&rp->lock);
-       rhine_set_carrier(&rp->mii_if);
 
        return rc;
 }
@@ -1838,7 +1887,6 @@ static int rhine_close(struct net_device *dev)
        spin_lock_irq(&rp->lock);
 
        netif_stop_queue(dev);
-       netif_poll_disable(dev);
 
        if (debug > 1)
                printk(KERN_DEBUG "%s: Shutting down ethercard, "
@@ -1857,6 +1905,9 @@ static int rhine_close(struct net_device *dev)
        spin_unlock_irq(&rp->lock);
 
        free_irq(rp->pdev->irq, dev);
+
+       flush_scheduled_work();
+
        free_rbufs(dev);
        free_tbufs(dev);
        free_ring(dev);
@@ -1920,8 +1971,7 @@ static void rhine_shutdown (struct pci_dev *pdev)
        }
 
        /* Hit power state D3 (sleep) */
-       if (!avoid_D3)
-               iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
+       iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
 
        /* TODO: Check use of pci_enable_wake() */
 
@@ -1958,7 +2008,7 @@ static int rhine_resume(struct pci_dev *pdev)
        if (!netif_running(dev))
                return 0;
 
-        if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
+        if (request_irq(dev->irq, rhine_interrupt, SA_SHIRQ, dev->name, dev))
                printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
 
        ret = pci_set_power_state(pdev, PCI_D0);