]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/8139too.c
twl4030-gpio use new gpiolib hooks
[linux-2.6-omap-h63xx.git] / drivers / net / 8139too.c
index 53bd903d2321c770cf9ad18dca6559712f86e51c..8a5b0d293f7548dbcfaa0e6b9267c21a1d0cf4dc 100644 (file)
@@ -98,7 +98,6 @@
 #include <linux/compiler.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/mii.h>
 #include <linux/completion.h>
 #include <linux/crc32.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <asm/irq.h>
 
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
                                  NETIF_MSG_LINK)
 
 
-/* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
-#ifdef CONFIG_8139TOO_PIO
-#define USE_IO_OPS 1
-#endif
-
 /* define to 1, 2 or 3 to enable copious debugging info */
 #define RTL8139_DEBUG 0
 
 
 #if RTL8139_DEBUG
 /* note: prints function name for you */
-#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
 #else
 #  define DPRINTK(fmt, args...)
 #endif
 #  define assert(expr) \
         if(unlikely(!(expr))) {                                        \
         printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n",        \
-        #expr,__FILE__,__FUNCTION__,__LINE__);                 \
+       #expr, __FILE__, __func__, __LINE__);                   \
         }
 #endif
 
 static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
+/* Whether to use MMIO or PIO. Default to MMIO. */
+#ifdef CONFIG_8139TOO_PIO
+static int use_io = 1;
+#else
+static int use_io = 0;
+#endif
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -219,7 +220,7 @@ enum {
 #define RTL8139B_IO_SIZE 256
 
 #define RTL8129_CAPS   HAS_MII_XCVR
-#define RTL8139_CAPS   HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define RTL8139_CAPS   (HAS_CHIP_XCVR|HAS_LNK_CHNG)
 
 typedef enum {
        RTL8139 = 0,
@@ -574,7 +575,6 @@ struct rtl8139_private {
        u32                     msg_enable;
        struct napi_struct      napi;
        struct net_device       *dev;
-       struct net_device_stats stats;
 
        unsigned char           *rx_ring;
        unsigned int            cur_rx; /* RX buf index of next pkt */
@@ -615,6 +615,8 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+module_param(use_io, int, 0);
+MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -710,13 +712,8 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
        assert (tp->pci_dev != NULL);
        pdev = tp->pci_dev;
 
-#ifdef USE_IO_OPS
-       if (tp->mmio_addr)
-               ioport_unmap (tp->mmio_addr);
-#else
        if (tp->mmio_addr)
                pci_iounmap (pdev, tp->mmio_addr);
-#endif /* USE_IO_OPS */
 
        /* it's ok to call this even if we have no regions to free */
        pci_release_regions (pdev);
@@ -791,32 +788,33 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        DPRINTK("PIO region size == 0x%02X\n", pio_len);
        DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
 
-#ifdef USE_IO_OPS
-       /* make sure PCI base addr 0 is PIO */
-       if (!(pio_flags & IORESOURCE_IO)) {
-               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) {
-               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)) {
-               dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-       if (mmio_len < RTL_MIN_IO_SIZE) {
-               dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
-               rc = -ENODEV;
-               goto err_out;
+retry:
+       if (use_io) {
+               /* make sure PCI base addr 0 is PIO */
+               if (!(pio_flags & IORESOURCE_IO)) {
+                       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) {
+                       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)) {
+                       dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
+               if (mmio_len < RTL_MIN_IO_SIZE) {
+                       dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
        }
-#endif
 
        rc = pci_request_regions (pdev, DRV_NAME);
        if (rc)
@@ -826,28 +824,28 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        /* enable PCI bus-mastering */
        pci_set_master (pdev);
 
-#ifdef USE_IO_OPS
-       ioaddr = ioport_map(pio_start, pio_len);
-       if (!ioaddr) {
-               dev_err(&pdev->dev, "cannot map PIO, aborting\n");
-               rc = -EIO;
-               goto err_out;
-       }
-       dev->base_addr = pio_start;
-       tp->mmio_addr = ioaddr;
-       tp->regs_len = pio_len;
-#else
-       /* ioremap MMIO region */
-       ioaddr = pci_iomap(pdev, 1, 0);
-       if (ioaddr == NULL) {
-               dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
-               rc = -EIO;
-               goto err_out;
+       if (use_io) {
+               ioaddr = pci_iomap(pdev, 0, 0);
+               if (!ioaddr) {
+                       dev_err(&pdev->dev, "cannot map PIO, aborting\n");
+                       rc = -EIO;
+                       goto err_out;
+               }
+               dev->base_addr = pio_start;
+               tp->regs_len = pio_len;
+       } else {
+               /* ioremap MMIO region */
+               ioaddr = pci_iomap(pdev, 1, 0);
+               if (ioaddr == NULL) {
+                       dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
+                       pci_release_regions(pdev);
+                       use_io = 1;
+                       goto retry;
+               }
+               dev->base_addr = (long) ioaddr;
+               tp->regs_len = mmio_len;
        }
-       dev->base_addr = (long) ioaddr;
        tp->mmio_addr = ioaddr;
-       tp->regs_len = mmio_len;
-#endif /* USE_IO_OPS */
 
        /* Bring old chips out of low-power mode. */
        RTL_W8 (HltClk, 'R');
@@ -953,6 +951,14 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
                           "Use the \"8139cp\" driver for improved performance and stability.\n");
        }
 
+       if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
+           pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
+           pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
+           pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
+               printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
+               use_io = 1;
+       }
+
        i = rtl8139_init_board (pdev, &dev);
        if (i < 0)
                return i;
@@ -1711,7 +1717,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
                dev_kfree_skb(skb);
        } else {
                dev_kfree_skb(skb);
-               tp->stats.tx_dropped++;
+               dev->stats.tx_dropped++;
                return 0;
        }
 
@@ -1762,27 +1768,27 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
                        if (netif_msg_tx_err(tp))
                                printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
                                        dev->name, txstatus);
-                       tp->stats.tx_errors++;
+                       dev->stats.tx_errors++;
                        if (txstatus & TxAborted) {
-                               tp->stats.tx_aborted_errors++;
+                               dev->stats.tx_aborted_errors++;
                                RTL_W32 (TxConfig, TxClearAbt);
                                RTL_W16 (IntrStatus, TxErr);
                                wmb();
                        }
                        if (txstatus & TxCarrierLost)
-                               tp->stats.tx_carrier_errors++;
+                               dev->stats.tx_carrier_errors++;
                        if (txstatus & TxOutOfWindow)
-                               tp->stats.tx_window_errors++;
+                               dev->stats.tx_window_errors++;
                } else {
                        if (txstatus & TxUnderrun) {
                                /* Add 64 to the Tx FIFO threshold. */
                                if (tp->tx_flag < 0x00300000)
                                        tp->tx_flag += 0x00020000;
-                               tp->stats.tx_fifo_errors++;
+                               dev->stats.tx_fifo_errors++;
                        }
-                       tp->stats.collisions += (txstatus >> 24) & 15;
-                       tp->stats.tx_bytes += txstatus & 0x7ff;
-                       tp->stats.tx_packets++;
+                       dev->stats.collisions += (txstatus >> 24) & 15;
+                       dev->stats.tx_bytes += txstatus & 0x7ff;
+                       dev->stats.tx_packets++;
                }
 
                dirty_tx++;
@@ -1818,7 +1824,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
        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++;
+       dev->stats.rx_errors++;
        if (!(rx_status & RxStatusOK)) {
                if (rx_status & RxTooLong) {
                        DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
@@ -1826,11 +1832,11 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
                        /* A.C.: The chip hangs here. */
                }
                if (rx_status & (RxBadSymbol | RxBadAlign))
-                       tp->stats.rx_frame_errors++;
+                       dev->stats.rx_frame_errors++;
                if (rx_status & (RxRunt | RxTooLong))
-                       tp->stats.rx_length_errors++;
+                       dev->stats.rx_length_errors++;
                if (rx_status & RxCRCErr)
-                       tp->stats.rx_crc_errors++;
+                       dev->stats.rx_crc_errors++;
        } else {
                tp->xstats.rx_lost_in_ring++;
        }
@@ -1890,7 +1896,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
 }
 
 #if RX_BUF_IDX == 3
-static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
+static inline void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
                                 u32 offset, unsigned int size)
 {
        u32 left = RX_BUF_LEN - offset;
@@ -1913,9 +1919,9 @@ static void rtl8139_isr_ack(struct rtl8139_private *tp)
        /* Clear out errors and receive interrupts */
        if (likely(status != 0)) {
                if (unlikely(status & (RxFIFOOver | RxOverflow))) {
-                       tp->stats.rx_errors++;
+                       tp->dev->stats.rx_errors++;
                        if (status & RxFIFOOver)
-                               tp->stats.rx_fifo_errors++;
+                               tp->dev->stats.rx_fifo_errors++;
                }
                RTL_W16_F (IntrStatus, RxAckBits);
        }
@@ -2016,8 +2022,8 @@ no_early_rx:
                        skb->protocol = eth_type_trans (skb, dev);
 
                        dev->last_rx = jiffies;
-                       tp->stats.rx_bytes += pkt_size;
-                       tp->stats.rx_packets++;
+                       dev->stats.rx_bytes += pkt_size;
+                       dev->stats.rx_packets++;
 
                        netif_receive_skb (skb);
                } else {
@@ -2025,7 +2031,7 @@ no_early_rx:
                                printk (KERN_WARNING
                                        "%s: Memory squeeze, dropping packet.\n",
                                        dev->name);
-                       tp->stats.rx_dropped++;
+                       dev->stats.rx_dropped++;
                }
                received++;
 
@@ -2072,7 +2078,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
        assert (ioaddr != NULL);
 
        /* Update the error count. */
-       tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+       dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
        RTL_W32 (RxMissed, 0);
 
        if ((status & RxUnderrun) && link_changed &&
@@ -2082,12 +2088,12 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
        }
 
        if (status & (RxUnderrun | RxErr))
-               tp->stats.rx_errors++;
+               dev->stats.rx_errors++;
 
        if (status & PCSTimeout)
-               tp->stats.rx_length_errors++;
+               dev->stats.rx_length_errors++;
        if (status & RxUnderrun)
-               tp->stats.rx_fifo_errors++;
+               dev->stats.rx_fifo_errors++;
        if (status & PCIErr) {
                u16 pci_cmd_status;
                pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
@@ -2227,12 +2233,11 @@ static int rtl8139_close (struct net_device *dev)
        RTL_W16 (IntrMask, 0);
 
        /* Update the error counts. */
-       tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+       dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
        RTL_W32 (RxMissed, 0);
 
        spin_unlock_irqrestore (&tp->lock, flags);
 
-       synchronize_irq (dev->irq);     /* racy, but that's ok here */
        free_irq (dev->irq, dev);
 
        rtl8139_tx_clear (tp);
@@ -2383,20 +2388,24 @@ static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
        np->msg_enable = datum;
 }
 
-/* TODO: we are too slack to do reg dumping for pio, for now */
-#ifdef CONFIG_8139TOO_PIO
-#define rtl8139_get_regs_len   NULL
-#define rtl8139_get_regs       NULL
-#else
 static int rtl8139_get_regs_len(struct net_device *dev)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *np;
+       /* TODO: we are too slack to do reg dumping for pio, for now */
+       if (use_io)
+               return 0;
+       np = netdev_priv(dev);
        return np->regs_len;
 }
 
 static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *np;
+
+       /* TODO: we are too slack to do reg dumping for pio, for now */
+       if (use_io)
+               return;
+       np = netdev_priv(dev);
 
        regs->version = RTL_REGS_VER;
 
@@ -2404,7 +2413,6 @@ static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs,
        memcpy_fromio(regbuf, np->mmio_addr, regs->len);
        spin_unlock_irq(&np->lock);
 }
-#endif /* CONFIG_8139TOO_MMIO */
 
 static int rtl8139_get_sset_count(struct net_device *dev, int sset)
 {
@@ -2472,12 +2480,12 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
 
        if (netif_running(dev)) {
                spin_lock_irqsave (&tp->lock, flags);
-               tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+               dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
                RTL_W32 (RxMissed, 0);
                spin_unlock_irqrestore (&tp->lock, flags);
        }
 
-       return &tp->stats;
+       return &dev->stats;
 }
 
 /* Set or clear the multicast filter for this adaptor.
@@ -2561,7 +2569,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
        RTL_W8 (ChipCmd, 0);
 
        /* Update the error counts. */
-       tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+       dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
        RTL_W32 (RxMissed, 0);
 
        spin_unlock_irqrestore (&tp->lock, flags);