]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/8139too.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
[linux-2.6-omap-h63xx.git] / drivers / net / 8139too.c
index 75317a14ad1cb26d6d3e030f48f0357dc6928789..0daf8c15e38118a0155abc2d3ee615e8c1369143 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>
                                  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
 
 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;
@@ -308,7 +309,7 @@ enum RTL8139_registers {
        Cfg9346         = 0x50,
        Config0         = 0x51,
        Config1         = 0x52,
-       FlashReg        = 0x54,
+       TimerInt        = 0x54,
        MediaStatus     = 0x58,
        Config3         = 0x59,
        Config4         = 0x5A,  /* absent on RTL-8139A */
@@ -324,6 +325,7 @@ enum RTL8139_registers {
        FIFOTMS         = 0x70,  /* FIFO Control and test. */
        CSCR            = 0x74,  /* Chip Status and Configuration Register. */
        PARA78          = 0x78,
+       FlashReg        = 0xD4, /* Communication with Flash ROM, four bytes. */
        PARA7c          = 0x7c,  /* Magic transceiver parameter register. */
        Config5         = 0xD8,  /* absent on RTL-8139A */
 };
@@ -614,6 +616,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);
@@ -709,13 +713,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);
@@ -790,32 +789,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)
@@ -825,28 +825,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');
@@ -952,6 +952,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;
@@ -1715,13 +1723,18 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
        }
 
        spin_lock_irqsave(&tp->lock, flags);
+       /*
+        * Writing to TxStatus triggers a DMA transfer of the data
+        * copied to tp->tx_buf[entry] above. Use a memory barrier
+        * to make sure that the device sees the updated data.
+        */
+       wmb();
        RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
                   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
        dev->trans_start = jiffies;
 
        tp->cur_tx++;
-       wmb();
 
        if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
                netif_stop_queue (dev);
@@ -2002,9 +2015,9 @@ no_early_rx:
                /* Malloc up new buffer, compatible with net-2e. */
                /* Omit the four octet CRC from the length. */
 
-               skb = dev_alloc_skb (pkt_size + 2);
+               skb = netdev_alloc_skb(dev, pkt_size + NET_IP_ALIGN);
                if (likely(skb)) {
-                       skb_reserve (skb, 2);   /* 16 byte align the IP fields. */
+                       skb_reserve (skb, NET_IP_ALIGN);        /* 16 byte align the IP fields. */
 #if RX_BUF_IDX == 3
                        wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
 #else
@@ -2381,20 +2394,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;
 
@@ -2402,7 +2419,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)
 {