WorkStruct: make allyesconfig
[safe/jmp/linux-2.6] / drivers / net / 8139too.c
index 9de58e2..931028f 100644 (file)
 */
 
 #define DRV_NAME       "8139too"
-#define DRV_VERSION    "0.9.27"
+#define DRV_VERSION    "0.9.28"
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
@@ -165,7 +164,7 @@ static int multicast_filter_limit = 32;
 static int debug = -1;
 
 /*
- * Receive ring size 
+ * Receive ring size
  * Warning: 64K ring has hardware issues and may lock up.
  */
 #if defined(CONFIG_SH_DREAMCAST)
@@ -229,7 +228,7 @@ typedef enum {
 
 
 /* indexed by board_t, above */
-static struct {
+static const struct {
        const char *name;
        u32 hw_flags;
 } board_info[] __devinitdata = {
@@ -257,7 +256,7 @@ static struct pci_device_id rtl8139_pci_tbl[] = {
        {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
        {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
        {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-       {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, 
+       {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 
 #ifdef CONFIG_SH_SECUREEDGE5410
        /* Bogus 8139 silicon reports 8129 without external PROM :-( */
@@ -505,7 +504,7 @@ enum chip_flags {
 #define HW_REVID_MASK  HW_REVID(1, 1, 1, 1, 1, 1, 1)
 
 /* directly indexed by chip_t, above */
-const static struct {
+static const struct {
        const char *name;
        u32 version; /* from RTL8139C/RTL8139D docs */
        u32 flags;
@@ -586,15 +585,16 @@ struct rtl8139_private {
        dma_addr_t tx_bufs_dma;
        signed char phys[4];            /* MII device addresses. */
        char twistie, twist_row, twist_col;     /* Twister tune state. */
-       unsigned int default_port:4;    /* Last dev->if_port value. */
+       unsigned int watchdog_fired : 1;
+       unsigned int default_port : 4;  /* Last dev->if_port value. */
+       unsigned int have_thread : 1;
        spinlock_t lock;
        spinlock_t rx_lock;
        chip_t chipset;
        u32 rx_config;
        struct rtl_extra_stats xstats;
 
-       struct work_struct thread;
-       long time_to_die;       /* -1 no thr, 0 thr active, 1 thr cancel */
+       struct delayed_work thread;
 
        struct mii_if_info mii;
        unsigned int regs_len;
@@ -629,16 +629,16 @@ static int rtl8139_poll(struct net_device *dev, int *budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void rtl8139_poll_controller(struct net_device *dev);
 #endif
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs);
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
 static int rtl8139_close (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
-static void rtl8139_thread (void *_data);
-static struct ethtool_ops rtl8139_ethtool_ops;
+static void rtl8139_thread (struct work_struct *work);
+static void rtl8139_tx_timeout_task(struct work_struct *work);
+static const struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
 /* Flush avoids rtl8139 bug w/ posted MMIO writes */
@@ -767,7 +767,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        /* dev and priv zeroed in alloc_etherdev */
        dev = alloc_etherdev (sizeof (*tp));
        if (dev == NULL) {
-               printk (KERN_ERR PFX "%s: Unable to alloc new net device\n", pci_name(pdev));
+               dev_err(&pdev->dev, "Unable to alloc new net device\n");
                return -ENOMEM;
        }
        SET_MODULE_OWNER(dev);
@@ -799,31 +799,31 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 #ifdef USE_IO_OPS
        /* make sure PCI base addr 0 is PIO */
        if (!(pio_flags & IORESOURCE_IO)) {
-               printk (KERN_ERR PFX "%s: region #0 not a PIO resource, aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
                rc = -ENODEV;
                goto err_out;
        }
        /* check for weird/broken PCI region reporting */
        if (pio_len < RTL_MIN_IO_SIZE) {
-               printk (KERN_ERR PFX "%s: Invalid PCI I/O region size(s), aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
                rc = -ENODEV;
                goto err_out;
        }
 #else
        /* make sure PCI base addr 1 is MMIO */
        if (!(mmio_flags & IORESOURCE_MEM)) {
-               printk (KERN_ERR PFX "%s: region #1 not an MMIO resource, aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
                rc = -ENODEV;
                goto err_out;
        }
        if (mmio_len < RTL_MIN_IO_SIZE) {
-               printk (KERN_ERR PFX "%s: Invalid PCI mem region size(s), aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
                rc = -ENODEV;
                goto err_out;
        }
 #endif
 
-       rc = pci_request_regions (pdev, "8139too");
+       rc = pci_request_regions (pdev, DRV_NAME);
        if (rc)
                goto err_out;
        disable_dev_on_err = 1;
@@ -834,7 +834,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 #ifdef USE_IO_OPS
        ioaddr = ioport_map(pio_start, pio_len);
        if (!ioaddr) {
-               printk (KERN_ERR PFX "%s: cannot map PIO, aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "cannot map PIO, aborting\n");
                rc = -EIO;
                goto err_out;
        }
@@ -845,7 +845,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        /* ioremap MMIO region */
        ioaddr = pci_iomap(pdev, 1, 0);
        if (ioaddr == NULL) {
-               printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev));
+               dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
                rc = -EIO;
                goto err_out;
        }
@@ -859,8 +859,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 
        /* check for missing/broken hardware */
        if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
-               printk (KERN_ERR PFX "%s: Chip not responding, ignoring board\n",
-                       pci_name(pdev));
+               dev_err(&pdev->dev, "Chip not responding, ignoring board\n");
                rc = -EIO;
                goto err_out;
        }
@@ -874,9 +873,10 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
                }
 
        /* if unknown chip, assume array element #0, original RTL-8139 in this case */
-       printk (KERN_DEBUG PFX "%s: unknown chip version, assuming RTL-8139\n",
-               pci_name(pdev));
-       printk (KERN_DEBUG PFX "%s: TxConfig = 0x%lx\n", pci_name(pdev), RTL_R32 (TxConfig));
+       dev_printk (KERN_DEBUG, &pdev->dev,
+                   "unknown chip version, assuming RTL-8139\n");
+       dev_printk (KERN_DEBUG, &pdev->dev,
+                   "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
        tp->chipset = 0;
 
 match:
@@ -953,9 +953,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
 
        if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
            pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev >= 0x20) {
-               printk(KERN_INFO PFX "pci dev %s (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n",
-                      pci_name(pdev), pdev->vendor, pdev->device, pci_rev);
-               printk(KERN_INFO PFX "Use the \"8139cp\" driver for improved performance and stability.\n");
+               dev_info(&pdev->dev,
+                          "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n",
+                          pdev->vendor, pdev->device, pci_rev);
+               dev_info(&pdev->dev,
+                          "Use the \"8139cp\" driver for improved performance and stability.\n");
        }
 
        i = rtl8139_init_board (pdev, &dev);
@@ -1008,7 +1010,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
                (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
        spin_lock_init (&tp->lock);
        spin_lock_init (&tp->rx_lock);
-       INIT_WORK(&tp->thread, rtl8139_thread, dev);
+       INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
        tp->mii.dev = dev;
        tp->mii.mdio_read = mdio_read;
        tp->mii.mdio_write = mdio_write;
@@ -1129,7 +1131,7 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
    No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
  */
 
-#define eeprom_delay() RTL_R32(Cfg9346)
+#define eeprom_delay() (void)RTL_R32(Cfg9346)
 
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD   (5)
@@ -1190,7 +1192,7 @@ static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_l
 #define mdio_delay()   RTL_R8(Config4)
 
 
-static char mii_2_8139_map[8] = {
+static const char mii_2_8139_map[8] = {
        BasicModeCtrl,
        BasicModeStatus,
        0,
@@ -1309,7 +1311,7 @@ static int rtl8139_open (struct net_device *dev)
        int retval;
        void __iomem *ioaddr = tp->mmio_addr;
 
-       retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
+       retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
        if (retval)
                return retval;
 
@@ -1339,9 +1341,9 @@ static int rtl8139_open (struct net_device *dev)
        netif_start_queue (dev);
 
        if (netif_msg_ifup(tp))
-               printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d"
-                       " GP Pins %2.2x %s-duplex.\n",
-                       dev->name, pci_resource_start (tp->pci_dev, 1),
+               printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d"
+                       " GP Pins %2.2x %s-duplex.\n", dev->name,
+                       (unsigned long long)pci_resource_start (tp->pci_dev, 1),
                        dev->irq, RTL_R8 (MediaStatus),
                        tp->mii.full_duplex ? "full" : "half");
 
@@ -1594,44 +1596,46 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
                 RTL_R8 (Config1));
 }
 
-static void rtl8139_thread (void *_data)
+static void rtl8139_thread (struct work_struct *work)
 {
-       struct net_device *dev = _data;
-       struct rtl8139_private *tp = netdev_priv(dev);
-
-       if ((tp->time_to_die == 0) &&
-           (rtnl_lock_interruptible() == 0)) {
+       struct rtl8139_private *tp =
+               container_of(work, struct rtl8139_private, thread.work);
+       struct net_device *dev = tp->mii.dev;
+       unsigned long thr_delay = next_tick;
+
+       if (tp->watchdog_fired) {
+               tp->watchdog_fired = 0;
+               rtl8139_tx_timeout_task(work);
+       } else if (rtnl_trylock()) {
                rtl8139_thread_iter (dev, tp, tp->mmio_addr);
                rtnl_unlock ();
+       } else {
+               /* unlikely race.  mitigate with fast poll. */
+               thr_delay = HZ / 2;
        }
 
-       if (tp->time_to_die == 0)
-               schedule_delayed_work(&tp->thread, next_tick);
+       schedule_delayed_work(&tp->thread, thr_delay);
 }
 
 static void rtl8139_start_thread(struct rtl8139_private *tp)
 {
        tp->twistie = 0;
-       tp->time_to_die = -1;
        if (tp->chipset == CH_8139_K)
                tp->twistie = 1;
        else if (tp->drv_flags & HAS_LNK_CHNG)
                return;
 
-       tp->time_to_die = 0;
+       tp->have_thread = 1;
 
        schedule_delayed_work(&tp->thread, next_tick);
 }
 
 static void rtl8139_stop_thread(struct rtl8139_private *tp)
 {
-       if (tp->time_to_die < 0)
-               return;
-
-       tp->time_to_die = 1;
-       wmb();
-
-       if (cancel_delayed_work(&tp->thread) == 0)
+       if (tp->have_thread) {
+               cancel_rearming_delayed_work(&tp->thread);
+               tp->have_thread = 0;
+       } else
                flush_scheduled_work();
 }
 
@@ -1643,14 +1647,14 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
        /* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
-
-static void rtl8139_tx_timeout (struct net_device *dev)
+static void rtl8139_tx_timeout_task (struct work_struct *work)
 {
-       struct rtl8139_private *tp = netdev_priv(dev);
+       struct rtl8139_private *tp =
+               container_of(work, struct rtl8139_private, thread.work);
+       struct net_device *dev = tp->mii.dev;
        void __iomem *ioaddr = tp->mmio_addr;
        int i;
        u8 tmp8;
-       unsigned long flags;
 
        printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
                "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
@@ -1671,23 +1675,34 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        if (tmp8 & CmdTxEnb)
                RTL_W8 (ChipCmd, CmdRxEnb);
 
-       spin_lock(&tp->rx_lock);
+       spin_lock_bh(&tp->rx_lock);
        /* Disable interrupts by clearing the interrupt mask. */
        RTL_W16 (IntrMask, 0x0000);
 
        /* Stop a shared interrupt from scavenging while we are. */
-       spin_lock_irqsave (&tp->lock, flags);
+       spin_lock_irq(&tp->lock);
        rtl8139_tx_clear (tp);
-       spin_unlock_irqrestore (&tp->lock, flags);
+       spin_unlock_irq(&tp->lock);
 
        /* ...and finally, reset everything */
        if (netif_running(dev)) {
                rtl8139_hw_start (dev);
                netif_wake_queue (dev);
        }
-       spin_unlock(&tp->rx_lock);
+       spin_unlock_bh(&tp->rx_lock);
 }
 
+static void rtl8139_tx_timeout (struct net_device *dev)
+{
+       struct rtl8139_private *tp = netdev_priv(dev);
+
+       if (!tp->have_thread) {
+               INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
+               schedule_delayed_work(&tp->thread, next_tick);
+       } else
+               tp->watchdog_fired = 1;
+
+}
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
@@ -1695,6 +1710,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned int entry;
        unsigned int len = skb->len;
+       unsigned long flags;
 
        /* Calculate the next Tx descriptor entry. */
        entry = tp->cur_tx % NUM_TX_DESC;
@@ -1711,7 +1727,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
 
-       spin_lock_irq(&tp->lock);
+       spin_lock_irqsave(&tp->lock, flags);
        RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
                   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
@@ -1722,7 +1738,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 
        if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
                netif_stop_queue (dev);
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_irqrestore(&tp->lock, flags);
 
        if (netif_msg_tx_queued(tp))
                printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
@@ -1811,7 +1827,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
        int tmp_work;
 #endif
 
-       if (netif_msg_rx_err (tp)) 
+       if (netif_msg_rx_err (tp))
                printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
                        dev->name, rx_status);
        tp->stats.rx_errors++;
@@ -1931,7 +1947,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-       while (netif_running(dev) && received < budget 
+       while (netif_running(dev) && received < budget
               && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
                u32 ring_offset = cur_rx % RX_BUF_LEN;
                u32 rx_status;
@@ -2018,7 +2034,7 @@ no_early_rx:
 
                        netif_receive_skb (skb);
                } else {
-                       if (net_ratelimit()) 
+                       if (net_ratelimit())
                                printk (KERN_WARNING
                                        "%s: Memory squeeze, dropping packet.\n",
                                        dev->name);
@@ -2131,8 +2147,7 @@ static int rtl8139_poll(struct net_device *dev, int *budget)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct rtl8139_private *tp = netdev_priv(dev);
@@ -2145,13 +2160,13 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
        status = RTL_R16 (IntrStatus);
 
        /* shared irq? */
-       if (unlikely((status & rtl8139_intr_mask) == 0)) 
+       if (unlikely((status & rtl8139_intr_mask) == 0))
                goto out;
 
        handled = 1;
 
        /* h/w no longer present (hotplug?) or major error, bail */
-       if (unlikely(status == 0xFFFF)) 
+       if (unlikely(status == 0xFFFF))
                goto out;
 
        /* close possible race's with dev_close */
@@ -2204,7 +2219,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
 static void rtl8139_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       rtl8139_interrupt(dev->irq, dev, NULL);
+       rtl8139_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -2431,7 +2446,7 @@ static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
        memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
 }
 
-static struct ethtool_ops rtl8139_ethtool_ops = {
+static const struct ethtool_ops rtl8139_ethtool_ops = {
        .get_drvinfo            = rtl8139_get_drvinfo,
        .get_settings           = rtl8139_get_settings,
        .set_settings           = rtl8139_set_settings,
@@ -2497,9 +2512,6 @@ static void __set_rx_mode (struct net_device *dev)
 
        /* Note: do not reorder, GCC is clever about common statements. */
        if (dev->flags & IFF_PROMISC) {
-               /* Unconditionally log net taps. */
-               printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n",
-                       dev->name);
                rx_mode =
                    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
                    AcceptAllPhys;
@@ -2614,7 +2626,7 @@ static int __init rtl8139_init_module (void)
        printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
 #endif
 
-       return pci_module_init (&rtl8139_pci_driver);
+       return pci_register_driver(&rtl8139_pci_driver);
 }