vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / 8139too.c
index 426273c..7d5b69a 100644 (file)
@@ -87,8 +87,6 @@
                "rtl8139-diag -mmmaaavvveefN" output
                enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
 
-               See 8139too.txt for more details.
-
 */
 
 #define DRV_NAME       "8139too"
 #include <linux/mii.h>
 #include <linux/completion.h>
 #include <linux/crc32.h>
-#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -171,7 +168,11 @@ static int debug = -1;
  * Receive ring size 
  * Warning: 64K ring has hardware issues and may lock up.
  */
+#if defined(CONFIG_SH_DREAMCAST)
+#define RX_BUF_IDX     1       /* 16K ring */
+#else
 #define RX_BUF_IDX     2       /* 32K ring */
+#endif
 #define RX_BUF_LEN     (8192 << RX_BUF_IDX)
 #define RX_BUF_PAD     16
 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
@@ -565,7 +566,6 @@ struct rtl8139_private {
        void *mmio_addr;
        int drv_flags;
        struct pci_dev *pci_dev;
-       u32 pci_state[16];
        u32 msg_enable;
        struct net_device_stats stats;
        unsigned char *rx_ring;
@@ -591,16 +591,18 @@ struct rtl8139_private {
        int time_to_die;
        struct mii_if_info mii;
        unsigned int regs_len;
+       unsigned long fifo_copy_timeout;
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM (multicast_filter_limit, "i");
-MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM (debug, "i");
+module_param(multicast_filter_limit, int, 0);
+module_param_array(media, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(debug, int, 0);
 MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
 MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
@@ -611,7 +613,7 @@ static int rtl8139_open (struct net_device *dev);
 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 val);
-static inline void rtl8139_start_thread(struct net_device *dev);
+static void rtl8139_start_thread(struct net_device *dev);
 static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -775,7 +777,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        u8 tmp8;
        int rc;
        unsigned int i;
-       u32 pio_start, pio_end, pio_flags, pio_len;
+       unsigned long pio_start, pio_end, pio_flags, pio_len;
        unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
        u32 version;
 
@@ -1622,8 +1624,7 @@ static int rtl8139_thread (void *data)
                do {
                        timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
                        /* make swsusp happy with our thread */
-                       if (current->flags & PF_FREEZE)
-                               refrigerator(PF_FREEZE);
+                       try_to_freeze(PF_FREEZE);
                } while (!signal_pending (current) && (timeout > 0));
 
                if (signal_pending (current)) {
@@ -1633,7 +1634,8 @@ static int rtl8139_thread (void *data)
                if (tp->time_to_die)
                        break;
 
-               rtnl_lock ();
+               if (rtnl_lock_interruptible ())
+                       break;
                rtl8139_thread_iter (dev, tp, tp->mmio_addr);
                rtnl_unlock ();
        }
@@ -1641,7 +1643,7 @@ static int rtl8139_thread (void *data)
        complete_and_exit (&tp->thr_exited, 0);
 }
 
-static inline void rtl8139_start_thread(struct net_device *dev)
+static void rtl8139_start_thread(struct net_device *dev)
 {
        struct rtl8139_private *tp = dev->priv;
 
@@ -1677,11 +1679,17 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        u8 tmp8;
        unsigned long flags;
 
-       DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
-                "media %2.2x.\n", dev->name,
-                RTL_R8 (ChipCmd),
-                RTL_R16 (IntrStatus),
-                RTL_R8 (MediaStatus));
+       printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
+               "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
+               RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
+       /* Emit info to figure out what went wrong. */
+       printk (KERN_DEBUG "%s: Tx queue start entry %ld  dirty entry %ld.\n",
+               dev->name, tp->cur_tx, tp->dirty_tx);
+       for (i = 0; i < NUM_TX_DESC; i++)
+               printk (KERN_DEBUG "%s:  Tx descriptor %d is %8.8lx.%s\n",
+                       dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
+                       i == tp->dirty_tx % NUM_TX_DESC ?
+                               " (queue head)" : "");
 
        tp->xstats.tx_timeouts++;
 
@@ -1694,15 +1702,6 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        /* Disable interrupts by clearing the interrupt mask. */
        RTL_W16 (IntrMask, 0x0000);
 
-       /* Emit info to figure out what went wrong. */
-       printk (KERN_DEBUG "%s: Tx queue start entry %ld  dirty entry %ld.\n",
-               dev->name, tp->cur_tx, tp->dirty_tx);
-       for (i = 0; i < NUM_TX_DESC; i++)
-               printk (KERN_DEBUG "%s:  Tx descriptor %d is %8.8lx.%s\n",
-                       dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
-                       i == tp->dirty_tx % NUM_TX_DESC ?
-                               " (queue head)" : "");
-
        /* Stop a shared interrupt from scavenging while we are. */
        spin_lock_irqsave (&tp->lock, flags);
        rtl8139_tx_clear (tp);
@@ -1714,7 +1713,6 @@ static void rtl8139_tx_timeout (struct net_device *dev)
                netif_wake_queue (dev);
        }
        spin_unlock(&tp->rx_lock);
-       
 }
 
 
@@ -1929,6 +1927,24 @@ static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
 }
 #endif
 
+static void rtl8139_isr_ack(struct rtl8139_private *tp)
+{
+       void *ioaddr = tp->mmio_addr;
+       u16 status;
+
+       status = RTL_R16 (IntrStatus) & RxAckBits;
+
+       /* Clear out errors and receive interrupts */
+       if (likely(status != 0)) {
+               if (unlikely(status & (RxFIFOOver | RxOverflow))) {
+                       tp->stats.rx_errors++;
+                       if (status & RxFIFOOver)
+                               tp->stats.rx_fifo_errors++;
+               }
+               RTL_W16_F (IntrStatus, RxAckBits);
+       }
+}
+
 static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                      int budget)
 {
@@ -1936,9 +1952,10 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
        int received = 0;
        unsigned char *rx_ring = tp->rx_ring;
        unsigned int cur_rx = tp->cur_rx;
+       unsigned int rx_size = 0;
 
        DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
-                " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+                " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
@@ -1946,10 +1963,8 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
               && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
                u32 ring_offset = cur_rx % RX_BUF_LEN;
                u32 rx_status;
-               unsigned int rx_size;
                unsigned int pkt_size;
                struct sk_buff *skb;
-               u16 status;
 
                rmb();
 
@@ -1978,10 +1993,24 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                 * since EarlyRx is disabled.
                 */
                if (unlikely(rx_size == 0xfff0)) {
+                       if (!tp->fifo_copy_timeout)
+                               tp->fifo_copy_timeout = jiffies + 2;
+                       else if (time_after(jiffies, tp->fifo_copy_timeout)) {
+                               DPRINTK ("%s: hung FIFO. Reset.", dev->name);
+                               rx_size = 0;
+                               goto no_early_rx;
+                       }
+                       if (netif_msg_intr(tp)) {
+                               printk(KERN_DEBUG "%s: fifo copy in progress.",
+                                      dev->name);
+                       }
                        tp->xstats.early_rx++;
-                       goto done;
+                       break;
                }
 
+no_early_rx:
+               tp->fifo_copy_timeout = 0;
+
                /* If Rx err or invalid rx_size/rx_status received
                 * (which happens if we get lost in the ring),
                 * Rx process gets reset, so we abort any further
@@ -1991,7 +2020,8 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                             (rx_size < 8) ||
                             (!(rx_status & RxStatusOK)))) {
                        rtl8139_rx_err (rx_status, dev, tp, ioaddr);
-                       return -1;
+                       received = -1;
+                       goto out;
                }
 
                /* Malloc up new buffer, compatible with net-2e. */
@@ -2027,19 +2057,11 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
                RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
 
-               /* Clear out errors and receive interrupts */
-               status = RTL_R16 (IntrStatus) & RxAckBits;
-               if (likely(status != 0)) {
-                       if (unlikely(status & (RxFIFOOver | RxOverflow))) {
-                               tp->stats.rx_errors++;
-                               if (status & RxFIFOOver)
-                                       tp->stats.rx_fifo_errors++;
-                       }
-                       RTL_W16_F (IntrStatus, RxAckBits);
-               }
+               rtl8139_isr_ack(tp);
        }
 
- done:
+       if (unlikely(!received || rx_size == 0xfff0))
+               rtl8139_isr_ack(tp);
 
 #if RTL8139_DEBUG > 1
        DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
@@ -2049,6 +2071,15 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
 #endif
 
        tp->cur_rx = cur_rx;
+
+       /*
+        * The receive buffer should be mostly empty.
+        * Tell NAPI to reenable the Rx irq.
+        */
+       if (tp->fifo_copy_timeout)
+               received = budget;
+
+out:
        return received;
 }
 
@@ -2458,14 +2489,13 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct rtl8139_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        spin_lock_irq(&np->lock);
-       rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
+       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&np->lock);
 
        return rc;
@@ -2558,6 +2588,8 @@ static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
        void *ioaddr = tp->mmio_addr;
        unsigned long flags;
 
+       pci_save_state (pdev);
+
        if (!netif_running (dev))
                return 0;
 
@@ -2575,8 +2607,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
 
        spin_unlock_irqrestore (&tp->lock, flags);
 
-       pci_set_power_state (pdev, 3);
-       pci_save_state (pdev, tp->pci_state);
+       pci_set_power_state (pdev, PCI_D3hot);
 
        return 0;
 }
@@ -2585,12 +2616,11 @@ static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
 static int rtl8139_resume (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
-       struct rtl8139_private *tp = dev->priv;
 
+       pci_restore_state (pdev);
        if (!netif_running (dev))
                return 0;
-       pci_restore_state (pdev, tp->pci_state);
-       pci_set_power_state (pdev, 0);
+       pci_set_power_state (pdev, PCI_D0);
        rtl8139_init_ring (dev);
        rtl8139_hw_start (dev);
        netif_device_attach (dev);